  /**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 扩展
*  
* 开发 流云
* 由 落阳 整理
* 最近更新：2016-01-27
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.menu.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
/***
 * 1:jeasyui.extensions.datagrid.autoMerge.js
 * 2:jeasyui.extensions.datagrid.updateColumn.js
 * 3:jeasyui.extensions.datagrid.getDom.js
 * 4:jeasyui.extensions.datagrid.getColumnInfo.js
 * 5:jeasyui.extensions.datagrid.getRowData.js
 * 6:jeasyui.extensions.datagrid.tooltip.js
 * 7:jeasyui.extensions.datagrid.rowState.js
 * 8:jeasyui.extensions.datagrid.rowContext.js
 * 9:jeasyui.extensions.datagrid.findRow.js
 * 10:jeasyui.extensions.datagrid.moveRow.js
 * 11:jeasyui.extensions.datagrid.operateRow.js
 * 12:jeasyui.extensions.datagrid.getCellData.js
 * 13:jeasyui.extensions.datagrid.operateColumn.js
 * 14:jeasyui.extensions.datagrid.navigating.js
 * 15:jeasyui.extensions.datagrid.liveSearch.js
 * 16:jeasyui.extensions.datagrid.highlightColumn.js
 * 17:jeasyui.extensions.datagrid.columnToggle.js
 * 18:jeasyui.extensions.datagrid.groupSummary.js
 * 19:jeasyui.extensions.datagrid.getColumnData.js
 * 20:jeasyui.extensions.datagrid.export.js
 * 21:jeasyui.extensions.datagrid.deleteRow.js
 * 22:jeasyui.extensions.datagrid.appendRow.js
 * 23:jeasyui.extensions.datagrid.editors.js
 * 24:jeasyui.extensions.datagrid.edit.cellEdit.js
 * 25:jeasyui.extensions.datagrid.edit.enterFocus.js
 * 26:jeasyui.extensions.datagrid.extEdit.js
 * 27:jeasyui.extensions.datagrid.fixed.cellMerge.js
 * 28:jeasyui.extensions.datagrid.moreEditors.js
 * 29:jeasyui.extensions.datagrid.edit.autoCount.js
 */

/** 
 * 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.autoMerge.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.getColumnInfo.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.columnToggle.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.rowContext.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.groupSummary.js" charset="utf-8"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.updateColumn.js" charset="utf-8"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.getDom.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.getRowData.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.tooltip.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.findRow.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.moveRow.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.operateRow.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.getCellData.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.operateColumn.js" charset="utf-8"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.navigating.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.liveSearch.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.highlightColumn.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.rowState.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.getColumnData.js" charset="utf-8"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.export.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.deleteRow.js" charset="utf-8"></script>  
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.appendRow.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.editors.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.edit.cellEdit.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.edit.enterFocus.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.fixed.cellMerge.js" charset="utf-8"></script> 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.extEdit.js" charset="utf-8"></script> 

 
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.edit.enterFocus.js" charset="utf-8"></script> 

 
   
<script type="text/javascript" src="${pageContext.request.contextPath}/scripts/jquery-easyui/jquery-easyui-extensions/datagrid/jeasyui.extensions.datagrid.edit.autoCount.js" charset="utf-8"></script> 
 * 
 */


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.rowState.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-24
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var autoMerge = function (target, fields) {
        var t = $(target);
        if (!fields) { fields = t.datagrid("getColumnFields"); }
        var rows = t.datagrid("getRows");
        var i = 0, j = 0, temp = {};
        for (i; i < rows.length; i++) {
            var row = rows[i];
            j = 0;
            for (j; j < fields.length; j++) {
                var field = fields[j];
                var tf = temp[field];
                if (!tf) {
                    tf = temp[field] = {};
                    tf[row[field]] = [i];
                } else {
                    var tfv = tf[row[field]];
                    if (tfv) {
                        tfv.push(i);
                    } else {
                        tfv = tf[row[field]] = [i];
                    }
                }
            }
        }
        $.each(temp, function (field, colunm) {
            $.each(colunm, function () {
                var group = this;

                if (group.length > 1) {
                    var before,
                    after,
                    megerIndex = group[0];
                    for (var i = 0; i < group.length; i++) {
                        before = group[i];
                        after = group[i + 1];
                        if (after && (after - before) == 1) {
                            continue;
                        }
                        var rowspan = before - megerIndex + 1;
                        if (rowspan > 1) {
                            t.datagrid('mergeCells', {
                                index: megerIndex,
                                type: "body",
                                field: field,
                                rowspan: rowspan
                            });
                        }
                        if (after && (after - before) != 1) {
                            megerIndex = after;
                        }
                    }
                }
            });
        });
    };



    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；判断指定的 data-row(数据行) 是否被 check；该方法的参数 index 表示要判断的行的索引号，从 0 开始计数；
        //  返回值：如果参数 index 所表示的 data-row(数据行) 被 check，则返回 true，否则返回 false。
        autoMergeCells: function (jq, fields) { return jq.each(function () { autoMerge(this, fields); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.getColumnInfo.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-02
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");



    $.fn.datagrid.extensions.getColumnFields = $.fn.datagrid.methods.getColumnFields;
    var getColumnFields = function (target, frozen) {
        var t = $(target);
        if (frozen == null || frozen == undefined) {
            return $.fn.datagrid.extensions.getColumnFields.call(t, t, frozen);
        }
        return $.type(frozen) == "string"
            ? $.array.merge([],
                $.fn.datagrid.extensions.getColumnFields.call(t, t, true),
                $.fn.datagrid.extensions.getColumnFields.call(t, t, false))
            : $.fn.datagrid.extensions.getColumnFields.call(t, t, frozen);
    };

    var getColumnOptions = function (target, frozen) {
        var t = $(target), fields = getColumnFields(target, frozen);
        return $.array.map(fields, function (val) { return t.datagrid("getColumnOption", val); });
    };

    var getNextColumnOption = function (target, field) {
        if (!field) {
            return undefined;
        }
        var fields = getColumnFields(target, "all");
        if (!fields || !fields.length) {
            return undefined;
        }
        var index = $.array.indexOf(fields, field);
        return index == -1 || index >= fields.length - 1
            ? undefined
            : $(target).datagrid("getColumnOption", fields[index + 1]);
    };

    var getPrevColumnOption = function (target, field) {
        if (!field) {
            return undefined;
        }
        var fields = getColumnFields(target, "all");
        if (!fields || !fields.length) {
            return undefined;
        }
        var index = $.array.indexOf(fields, field);
        return index < 1
            ? undefined
            : $(target).datagrid("getColumnOption", fields[index - 1]);
    };


    var methods = $.fn.datagrid.extensions.methods = {

        //  重写 easyui-datagrid 的 getColumnFields 方法；获取 easyui-datagrid 所有列的 field 所组成的一个数组集合；参数 frozen 可以定义为如下格式：
        //      Boolean 类型值：如果是 true，则表示返回的结果集中包含 frozen(冻结)列，如果是 false 则表示返回的结果集中不包含 frozen(冻结)列；
        //      String 类型值：如果该参数定义为任意 String 类型值，则返回所有列信息(包括 frozen 冻结列和非冻结列)；
        //  返回值：如果 frozen 参数定义为 Boolean 且为 true，则返回所有 frozen(冻结) 列的 field 所构成的一个 Array 数组对象；
        //      如果 frozen 参数定义为 false，则返回所有非 frozen(非冻结) 列的 field 所构成的一个 Array 数组对象；
        //      如果 frozen 定义为任意的 String 类型值，则返回所有列的 field 所构成的一个 Array 数组对象。
        //  落阳注：重写该方法是为了使方法能返回“冻结列与非冻结列所构成的一个 Array 数组对象”。
        getColumnFields: function (jq, frozen) { return getColumnFields(jq[0], frozen); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 所有列的 columnOption 所组成的一个数组集合；参数 frozen 可以定义为如下格式：
        //      Boolean 类型值：如果是 true，则表示返回的结果集中包含 frozen(冻结)列，如果是 false 则表示返回的结果集中不包含 frozen(冻结)列；
        //      String 类型值：如果该参数定义为任意 String 类型值，则返回所有列信息(包括 frozen 冻结列和非冻结列)；
        //  返回值：如果 frozen 参数定义为 Boolean 且为 true，则返回所有 frozen(冻结) 列的 columnOption 所构成的一个 Array 数组对象；
        //      如果 frozen 参数定义为 false，则返回所有非 frozen(非冻结) 列的 columnOption 所构成的一个 Array 数组对象；
        //      如果 frozen 定义为任意的 String 类型值，则返回所有列的 columnOption 所构成的一个 Array 数组对象。
        getColumnOptions: function (jq, frozen) { return getColumnOptions(jq[0], frozen); },

        //  扩展 easyui-datagrid 的自定义方法；获取指定列的下一格位置列的 列属性(columnOption) 信息；该方法的参数 field 表示指定列的 field 值。
        //  返回值：当前指定列的下一格位置的列的 列属性(columnOption) 信息。
        //      如果不存在指定的列，或者指定列的下一格位置没有其他列，则返回 undefined。
        getNextColumnOption: function (jq, field) { return getNextColumnOption(jq[0], field); },

        //  扩展 easyui-datagrid 的自定义方法；获取指定列的上一格位置列的 列属性(columnOption) 信息；该方法的参数 field 表示指定列的 field 值。
        //  返回值：当前指定列的上一格位置的列的 列属性(columnOption) 信息。
        //      如果不存在指定的列，或者指定列的上一格位置没有其他列，则返回 undefined。
        getPrevColumnOption: function (jq, field) { return getPrevColumnOption(jq[0], field); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 扩展
* jeasyui.extensions.datagrid.columnToggle.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2016-01-27
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.menu.js
*   3、jeasyui.extensions.datagrid.getColumnInfo.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function ($) {

    $.util.namespace("$.fn.datagrid.extensions");


    function isMultiLineHeaders(target) {
        var state = $.data(target, "datagrid"),
            opts = state.options;
        if (opts.columns && opts.columns.length > 1 && opts.columns[0].length && opts.columns[1].length) {
            return true;
        }
        if (opts.frozenColumns && opts.frozenColumns.length > 1 && opts.frozenColumns[0].length && opts.frozenColumns[1].length) {
            return true;
        }
        return false;
    }

    var getColumnData = function (target, field, withFormatter) {
        var t = $(target), rows = t.datagrid("getRows");
        if (withFormatter === false) {
            return $.array.map(rows, function (val) { return val[field]; });
        } else {
            var colsOptions = t.datagrid("getColumnOptions", "true"), theColOpts = $.array.first(colsOptions, function (item) { return item.field == field; });
            if(!theColOpts){
                return [];
            }
            return $.isFunction(theColOpts.formatter) ? $.array.map(rows, function (row) { return theColOpts.formatter.call(target, row[field], row, t.datagrid("getRowIndex", row)); }) : $.array.map(rows, function (row) { return row[field]; });
        }
    };

    var getDistinctColumnData = function (target, field, withFormatter) {
        var t = $(target), data = getColumnData(target, field, withFormatter);
        return $.array.distinct(data);
    };

    var getRowDom = function (target, index) {
        if (!$.isNumeric(index) || index < 0) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel");
        return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "]");
    };

    function findRow(target, param, t, opts, rows) {
        t = t && t.length ? t : $(target);
        opts = opts ? opts : $.data(target, "datagrid").options;
        rows = rows && rows.length ? rows : t.datagrid("getRows");
        var type = $.type(param);
        if (type == "function") {
            return $.array.first(rows, function (row, index) {
                return param.call(target, row, index, rows);
            });
        } else if (type == "object") {
            return opts.idField && (opts.idField in param)
                ? findRowById(param[opts.idField])
                : $.array.first(rows, function (val) { return val == param; });
        } else {
            return findRowById(param);
        }
        function findRowById(id) {
            return $.array.first(rows, function (row) {
                return row[opts.idField] == id;
            });
        }
    }

    function findRows(target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options,
            rows = t.datagrid("getRows");
        if ($.isFunction(param)) {
            return $.array.filter(rows, function (val, index) {
                return param.call(target, val, index, rows);
            });
        } else if ($.array.likeArrayNotString(param)) {
            var array = $.array.map(param, function (val) {
                return findRow(target, val, t, opts, rows);
            });
            return $.array.filter(array, function (val) {
                return val != null && val != undefined;
            });
        } else {
            return [findRow(target, param, t, opts, rows)];
        }
    }

    //  param: idField | row | function (row, index, rows)
    function showRow(target, param) {
        var state = $.data(target, "datagrid"),
            t = $(target),
            opts = state.options,
            rows = t.datagrid("getRows");

        var row = findRow(target, param),
            index = t.datagrid("getRowIndex", row);
        if (index > -1) {
            $.array.remove(state.hiddenRows, row);
            getRowDom(target, index).removeClass("datagrid-row-hidden");
        }
    }

    //  param: idField | row | function (row, index, rows)
    function hideRow(target, param) {
        var state = $.data(target, "datagrid"),
            t = $(target),
            opts = state.options,
            rows = t.datagrid("getRows");

        var row = findRow(target, param),
            index = t.datagrid("getRowIndex", row);
        if (index > -1) {
            $.array.attach(state.hiddenRows, row);
            t.datagrid("unselectRow", index).datagrid("uncheckRow", index);
            getRowDom(target, index).addClass("datagrid-row-hidden");
        }
    }

    //  param: function (row, index, rows) | array (idField | row | function (row, index, rows)) | boolean (false)
    function hideRows(target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        if (param == true) {
            var rows = t.datagrid("getRows");
            $.array.clear(state.hiddenRows);
            $.array.copy(state.hiddenRows, rows);
            $.each(rows, function (i, n) {
                var rowIndex = t.datagrid("getRowIndex", n);
                if (rowIndex > -1) {
                    getRowDom(target, rowIndex).addClass("datagrid-row-hidden");
                }
            });
        } else {
            var array = findRows(target, param);
            if (array.length) {
                $.each(array, function (i, n) {
                    hideRow(target, n);
                });
            }
        }
    }

    //  param: function (index, row, rows) | array (idField | row | function (index, row, rows)) | boolean (true)
    function showRows(target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        if (param == true) {
            var rows = t.datagrid("getRows");
            $.array.clear(state.hiddenRows);
            $.each(rows, function (i, n) {
                var rowIndex = t.datagrid("getRowIndex", n);
                if (rowIndex > -1) {
                    getRowDom(target, rowIndex).removeClass("datagrid-row-hidden");
                }
            });
        } else {
            var array = findRows(target, param);
            if (array.length) {
                $.each(array, function (i, n) {
                    showRow(target, n);
                });
            }
        }
    }



    function getHeaderMenuItems(t, opts, e, field) {
        var menuItems = [],
            defaultMenuItems = [],
            args = [t[0], field];

        $.array.merge(defaultMenuItems, defaultMenuItems.length ? "-" : [], $.fn.datagrid.extensions.sortMenus);
        $.array.merge(defaultMenuItems, defaultMenuItems.length ? "-" : [], $.fn.datagrid.extensions.fieldToggleMenus);
        $.array.merge(defaultMenuItems, defaultMenuItems.length ? "-" : [], $.fn.datagrid.extensions.rowToggleMenus);

        if ($.array.likeArrayNotString(opts.headerContextMenu)) {
            $.array.merge(menuItems, menuItems.length ? "-" : [], opts.headerContextMenu);
        }
        if (defaultMenuItems.length) {
            $.array.merge(menuItems, menuItems.length ? "-" : [], defaultMenuItems);
        }
        return $.easyui.parseMenuItems(menuItems, args);
    }

    function initHeaderCellClickMenu(t, opts, tdDom) {
        var td = $(tdDom),
            cell = td.find("div.datagrid-cell"),
            arrow = $("<span class='s-btn-downarrow datagrid-header-cell-arrow'>&nbsp;</span>").prependTo(cell).click(function (e) {
                $.easyui.hideAllMenu();
                var s = $(this),
                    offset = s.offset(),
                    height = s.outerHeight(),
                    field = s.closest("td[field]").attr("field"),
                    menuItems = getHeaderMenuItems(t, opts, e, field),
                    mm = $.easyui.showMenu({
                        items: menuItems,
                        left: offset.left,
                        top: offset.top + height
                    }),
                    mopts = mm.menu("options"),
                    onHide = mopts.onHide;
                arrow.hidden = false;
                mopts.onHide = function () {
                    arrow.hidden = true;
                    arrow.removeClass("datagrid-header-cell-arrow-show");
                    onHide.apply(this, arguments);
                };
                e.stopPropagation();
            });
        td.unbind(".arrow-hover").bind({
            "mouseenter.arrow-hover": function () {
                arrow.addClass("datagrid-header-cell-arrow-show");
            },
            "mouseleave.arrow-hover": function () {
                if (arrow.hidden == null || arrow.hidden == undefined || arrow.hidden) {
                    arrow.removeClass("datagrid-header-cell-arrow-show");
                }
            }
        });
    }

    function getHeaderFields(t) {
        return t.datagrid("getPanel").find("div.datagrid-view div.datagrid-header table.datagrid-htable tr.datagrid-header-row td[field]").filter(function () {
            var td = $(this),
                colspan = td.attr("colspan"),
                field = td.attr("field"),
                copts = t.datagrid("getColumnOption", field);
            return (!colspan || colspan == "1") && !td.is(".datagrid-cell-rownumber") && copts && !copts.checkbox ? true : false;
        });
    }


    // 排序菜单
    $.fn.datagrid.extensions.sortMenus = [
        {
            text: "升序", iconCls: "icon-standard-hmenu-asc",
            disabled: function (e, menuItem, menu, target, field) {
                var t = $(target),
                    copts = t.datagrid("getColumnOption", field);
                return copts.sortable && (copts.colspan == null || copts.colspan == undefined || copts.colspan == 1) ? false : true;
            },
            handler: function (e, menuItem, menu, target, field) {
                return $(target).datagrid("sort", { sortName: field, sortOrder: "asc" });
            }
        },
        {
            text: "降序", iconCls: "icon-standard-hmenu-desc",
            disabled: function (e, menuItem, menu, target, field) {
                var t = $(target),
                    copts = t.datagrid("getColumnOption", field);
                return copts.sortable && (copts.colspan == null || copts.colspan == undefined || copts.colspan == 1) ? false : true;
            },
            handler: function (e, menuItem, menu, target, field) {
                return $(target).datagrid("sort", {
                    sortName: field, sortOrder: "desc"
                });
            }
        }
    ];

    // 列显隐菜单
    $.fn.datagrid.extensions.fieldToggleMenus = [
        {
            text: "显示/隐藏列", iconCls: "icon-standard-application-view-columns",
            disabled: false,
            children: function (e, menuItem, menu, target, field) {
                var t = $(target),
                    mm = $(menu),
                    menuItems = [],
                    topMenus = getFieldTopMenus(t, mm),
                    fieldMenus = getFieldToggleMenus(t, mm);
                if (topMenus.length) {
                    $.array.merge(menuItems, menuItems.length ? "-" : [], topMenus);
                }
                if (fieldMenus.length) {
                    $.array.merge(menuItems, menuItems.length ? "-" : [], fieldMenus);
                }
                return menuItems;
            }
        }
    ];
    // 列显隐菜单中的置顶菜单
    function getFieldTopMenus(t, mm) {
        var target = t[0],
            state = $.data(target, "datagrid"),
            cols = $.array.filter(t.datagrid("getColumnOptions", false), function (col) {
                return col.field ? true : false;
            }),
            originalCols = state.originalColumnOptions;
        return [
            {
                text: "显示全部列", hideOnClick: false,
                iconCls: function () {
                    var len = cols.length,
                        count = $.array.sum(cols, function (col) {
                            return col.hidden ? 0 : 1;
                        });
                    return count >= len ? "tree-checkbox1" : (count == 0 ? "tree-checkbox0" : "tree-checkbox2");
                },
                handler: function () {
                    $.each(cols, function (i, col) { t.datagrid("showColumn", col.field); });
                    $(this).parent().children(".menu-item:not(:eq(1))").each(function () {
                        var item = mm.menu("getItem", this);
                        if (item.disabled) { return; }
                        mm.menu("setIcon", { target: this, iconCls: "tree-checkbox1" })
                            .menu("enableItem", this);
                    });
                }
            },
            {
                text: "还原默认", iconCls: "icon-standard-application-view-tile", hideOnClick: false,
                handler: function () {
                    $.each(originalCols, function (i, col) {
                        t.datagrid(col.hidden ? "hideColumn" : "showColumn", col.field);
                    });
                    var mp = $(this).parent();
                    mp.children("div.menu-item:gt(1)").each(function () {
                        var title = $(this).text(),
                            col = $.array.first(originalCols, function (val) {
                                return val.title == title;
                            });
                        var item = mm.menu("getItem", this);
                        if (item.disabled) { return; }
                        if (col) {
                            mm.menu("setIcon", {
                                target: this,
                                iconCls: col.hidden ? "tree-checkbox0" : "tree-checkbox1"
                            });
                        }
                        mm.menu("enableItem", this);
                    });
                    mp.children("div.menu-item:first").each(function () {
                        var len = cols.length,
                            count = $.array.sum(cols, function (col) {
                                return col.hidden ? 0 : 1;
                            });
                        mm.menu("setIcon", {
                            target: this,
                            iconCls: count >= len ? "tree-checkbox1" : (count == 0 ? "tree-checkbox0" : "tree-checkbox2")
                        });
                    });
                }
            }
        ];
    }
    // 列显隐菜单中的显隐菜单
    function getFieldToggleMenus(t, mm) {
        var target = t[0],
            cols = $.array.filter(t.datagrid("getColumnOptions", false), function (col) {
                return col.field ? true : false;
            });
        return $.array.map(cols, function (col) {
            return {
                text: col.title || col.field,
                iconCls: col.hidden ? "tree-checkbox0" : "tree-checkbox1",
                hideOnClick: false,
                disabled: !col.hidable ? true : false,
                handler: function () {
                    var mi = $(this),
                        mp = mi.parent(),
                        mip = mp.find(".menu-item:gt(1)"),
                        mis = mip.find(".tree-checkbox1"),
                        copts = t.datagrid("getColumnOption", col.field);
                    if (!col.hidable) {
                        return;
                    }
                    t.datagrid(copts.hidden ? "showColumn" : "hideColumn", col.field);
                    mm.menu("setIcon", {
                        target: this,
                        iconCls: copts.hidden ? "tree-checkbox0" : "tree-checkbox1"
                    });
                    var length = cols.length,
                        count = $.array.sum(cols, function (col) {
                            return col.hidden ? 0 : 1;
                        });
                    mm.menu("setIcon", {
                        target: mi.parent().children("div.menu-item:first"),
                        iconCls: count >= length ? "tree-checkbox1" : (count == 0 ? "tree-checkbox0" : "tree-checkbox2")
                    });

                    var mms = mip.filter(function () {
                        return $(".tree-checkbox1", this).length ? true : false;
                    });

                    // 为了确保“至少有一个列显示”，当判定显示的列仅剩1个时禁用对该列的隐藏菜单
                    // 但因此对菜单项的隐藏，要与 列不可隐藏 导致的隐藏进行区分
                    // 找到所有 不可隐藏 的列信息，并按照菜单项的文本信息格式（<span>项名</span>）组成数组
                    var hidableColTitles = $.array.filter(cols, function (itemCol) { return !itemCol.hidable; }).map(function (itemCol) { return "<span>" + t.datagrid("getColumnOption", itemCol.field).title + "</span>"; });
                    mms.each(function () {
                        var item = mm.menu('getItem', this);
                        if (!$.array.contains(hidableColTitles, item.text)) {
                            mm.menu(mms.length > 1 ? "enableItem" : "disableItem", this);
                        }
                    });
                }
            };
        });
    }

    // 行显隐菜单
    $.fn.datagrid.extensions.rowToggleMenus = [
        {
            text: "过滤/显示", iconCls: "icon-standard-application-view-list",
            disabled: function (e, menuItem, menu, target, field) {
                var t = $(target),
                    copts = t.datagrid("getColumnOption", field);
                return copts.filterable && (copts.colspan == null || copts.colspan == undefined || copts.colspan == 1) ? false : true;
            },
            children: function (e, menuItem, menu, target, field) {
                var t = $(target),
                    rows = t.datagrid("getRows"),
                    colOpts = t.datagrid("getColumnOption", field);
                fieldValues = getDistinctColumnData(target, field, !colOpts.ignoreFormatterWhenFilter),
                    mm = $(menu),
                    menuItems = [],
                    topMenus = getRowTopMenus(t, mm, rows, fieldValues),
                    rowMenus = getRowToggleMenus(t, field, mm, rows, fieldValues, e);
                if (topMenus.length) {
                    $.array.merge(menuItems, menuItems.length ? "-" : [], topMenus);
                }
                if (rowMenus.length) {
                    $.array.merge(menuItems, menuItems.length ? "-" : [], rowMenus);
                }
                return menuItems;
            }
        }
    ];
    // 行显隐菜单中的置顶菜单
    function getRowTopMenus(t, mm, rows, fieldValues) {
        var target = t[0],
            state = $.data(target, "datagrid");
        return [
            {
                text: "全部", hideOnClick: false,
                iconCls: function () {
                    return !state.hiddenRows.length ? "tree-checkbox1" : (state.hiddenRows.length >= rows.length ? "tree-checkbox0" : "tree-checkbox2");
                },
                handler: function () {
                    if (state.hiddenRows.length) {
                        showRows(target, true);
                    } else {
                        hideRows(target, true);
                    }
                    $(this).parent().children("div.menu-item[hideOnClick=false]").each(function () {
                        mm.menu("setIcon", {
                            target: this,
                            iconCls: state.hiddenRows.length ? "tree-checkbox0" : "tree-checkbox1"
                        });
                    });
                }
            }
        ];
    }
    // 行显隐菜单中的显隐菜单
    function getRowToggleMenus(t, field, mm, rows, fieldValues, e) {
        var target = t[0],
            state = $.data(target, "datagrid"),
            opts = state.options,
            hasMore = fieldValues.length > opts.headerFilterMenuLength,
            array = hasMore ? $.array.left(fieldValues, opts.headerFilterMenuLength) : fieldValues,
            menuItems = $.array.map(array, function (val) {
                var hrows = $.array.filter(rows, function (row) { return row[field] == val; });
                return {
                    text: val, hideOnClick: false,
                    iconCls: function () {
                        var hcells = $.array.filter(state.hiddenRows, function (row) { return row[field] == val; });
                        return !hcells.length
                            ? "tree-checkbox1"
                            : (hcells.length >= hrows.length ? "tree-checkbox0" : "tree-checkbox2");
                    },
                    handler: function () {
                        var hcells = $.array.filter(state.hiddenRows, function (row) { return row[field] == val; });
                        hcells.length ? showRows(target, hrows) : hideRows(target, hrows);
                        mm.menu("setIcon", {
                            target: this,
                            iconCls: hcells.length ? "tree-checkbox1" : "tree-checkbox0"
                        });
                        $(this).parent().children("div.menu-item:first").each(function () {
                            mm.menu("setIcon", {
                                target: this,
                                iconCls: (!state.hiddenRows.length)
                                    ? "tree-checkbox1"
                                    : (state.hiddenRows.length >= rows.length ? "tree-checkbox0" : "tree-checkbox2")
                            });
                        });
                    }
                };
            });
        if (hasMore) {
             $.array.merge(menuItems, menuItems.length ? "-" : [], {
                text: "处理更多(共" + fieldValues.length + "项)...",
                iconCls: "icon-standard-application-view-detail",
                handler: function () {
                    showFilterDialog(target, field, rows, fieldValues);
                }
            });
        }
        return menuItems;
    }
    // 完整的列数据过滤窗口
    function showFilterDialog(target, field, rows, fieldValues) {
        if (!field) {
            return;
        }
        var t = $(target);
        rows = rows && rows.length ? rows : t.datagrid("getRows");
        fieldValues = fieldValues && fieldValues.length ? fieldValues : getDistinctColumnData(target, field, true);

        var state = $.data(target, "datagrid"),
            copts = t.datagrid("getColumnOption", field),
            title = copts.title || copts.field;

        var d = top.$("<div />").appendTo($("body")).dialog({
            title: "过滤/显示",
            iconCls: "icon-standard-application-view-detail",
            height: 300,
            width: 220,
            modal: true,
            resizable: true,
            toolbar: [
                    {
                        text: "全部选择", iconCls: "icon-standard-accept",
                        handler: function () {
                            showRows(target, true);
                            d.dialog("body").find(":checkbox").each(function () { this.checked = true; });
                        }
                    },
                    {
                        text: "全部不选", iconCls: "icon-standard-cancel",
                        handler: function () {
                            hideRows(target, true);
                            d.dialog("body").find(":checkbox").each(function () { this.checked = false; });
                        }
                    }
            ]
        }),
        body = d.dialog("body"),
        l = $("<div>"
                + "<div class=\"datagrid-filters-dialog-layout-north\" data-options=\"region: 'north', split: false, border: false\" >列：" + title + "，共" + fieldValues.length + "项</div>"
                + "<div class=\"datagrid-filters-dialog-layout-center\" data-options=\"region: 'center', border: false\" ></div>"
                + "</div>").appendTo(body).layout({
                    fit: true
                }),
        b = l.layout("panel", "center"),
        ul = $("<ul></ul>").appendTo(b);

        $.each(fieldValues, function (i, text) {
            var id = "item_ck_" + $.util.guid("N"),
                checked = !$.array.some(state.hiddenRows, function (val) {
                    return val[field] == text;
                }),
                li = $("<li></li>").appendTo(ul),
                ck = $("<input />").attr({
                    type: "checkbox",
                    id: id,
                    checked: checked
                }).appendTo(li),
                label = $("<label></label>").attr("for", id).text(text).appendTo(li);
            ck.click(function () {
                var hrows = $.array.filter(rows, function (row) { return row[field] == text; }),
                    hcells = $.array.filter(state.hiddenRows, function (row) { return row[field] == text; });
                hcells.length ? showRows(target, hrows) : hideRows(target, hrows);
            });
        });
    }




    // 初始化列 options 扩展属性
    // 缓存有 title 值的非冻结列 options
    function initExtendColumnOptions(t, opts) {
        var target = t[0],
            state = $.data(target, "datagrid"),
            cols = t.datagrid("getColumnOptions", "all");
        $.each(cols, function (i, col) {
            $.union(col, $.fn.datagrid.extensions.columnOptions);
        });
        var columnOptions = t.datagrid("getColumnOptions", false);
        state.columnOptions = $.array.filter(columnOptions, function (col) {
            return col.title ? true : false;
        });
        state.originalColumnOptions = $.array.map(state.columnOptions, function (col) {
            return $.extend({}, col);
        });
        state.multiLineHeaders = isMultiLineHeaders(target);
    }

    // 初始化表头过滤数据
    function initHeaderFiltersData(t, opts) {
        var target = t[0],
            state = $.data(target, "datagrid");
        state.hiddenRows = [];
    }

    // 隐藏所有 menu 面板
    function initDisposeEvent(t, opts) {
        t.datagrid("getPanel").panel("body").undelegate(".datagrid-extensions").delegate("tr.datagrid-header-row, tr.datagrid-row", "click.datagrid-extensions", function () {
            $.easyui.hideAllMenu();
        });
    }

    // 初始化表头右键菜单
    function initHeaderContextMenu(t, opts) {
        t.datagrid("getPanel").panel("body").delegate("tr.datagrid-header-row>td[field]", "contextmenu.datagrid-extensions", function (e) {
            var td = $(this),
                field = td.attr("field");
            if (!field) {
                return;
            }
            if (opts.enableHeaderContextMenu) {
                e.preventDefault();
                var menuItems = getHeaderMenuItems(t, opts, e, field);
                $.easyui.showMenu({ items: menuItems, left: e.pageX, top: e.pageY, event: e });
            }
        });
    }

    // 初始化表头点击菜单
    function initHeaderClickMenu(t, opts) {
        if (opts.enableHeaderClickMenu) {
            getHeaderFields(t).each(function () {
                initHeaderCellClickMenu(t, opts, this);
            });
        }
    }


    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initExtendColumnOptions(t, opts);
        initHeaderFiltersData(t, opts);
        initDisposeEvent(t, opts);
        initHeaderContextMenu(t, opts);
        initHeaderClickMenu(t, opts);
    }


    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this, [
                            {
                                headerFilterMenuLength: "number",
                            },
                            {
                                enableHeaderContextMenu: "boolean",
                                enableHeaderClickMenu: "boolean",
                                autoHighlightColumn: "boolean"
                            }
                        ]), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);


    var columnOptions = {

        // 表示该列是否可隐藏，其值可以是 Boolean 类型；
        // 默认为 true。
        // 该属性用于在“列显隐”时判定
        hidable: true,

        // 表示该列是否可过滤，其值可以是 Boolean 类型；
        // 默认为 true。
        // 该属性用于在“列过滤”时判定
        filterable: true,

        // 表示该列在 filterable 为 true 显示列数据时是否忽略 formatter 的存在，其值可以是 Boolean 类型；
        // 默认为 false
        // 该属性用于在“列过滤显示数据时”时判定
        ignoreFormatterWhenFilter: false
    };
    if ($.fn.datagrid.extensions.columnOptions) {
        $.extend($.fn.datagrid.extensions.columnOptions, columnOptions);
    }
    else {
        $.fn.datagrid.extensions.columnOptions = columnOptions;
    }


    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用 easyui-datagrid 的表头右键菜单；
        //  Boolean 类型值，默认为 true。
        enableHeaderContextMenu: true,

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用 easyui-datagrid 的表头列点击按钮菜单；
        //  Boolean 类型值，默认为 true。 
        enableHeaderClickMenu: true,

        //  扩展 easyui-datagrid 的自定义属性，该属性表示表列头右键菜单，为一个 Array 对象；数组中的每一个元素都具有如下属性:
        //      id:         表示菜单项的 id；
        //      text:       表示菜单项的显示文本；
        //      iconCls:    表示菜单项的左侧显示图标；
        //      disabled:   表示菜单项是否被禁用(禁用的菜单项点击无效)；
        //      hideOnClick:    表示该菜单项点击后整个右键菜单是否立即自动隐藏；
        //      bold:           Boolean 类型值，默认为 false；表示该菜单项是否字体加粗；
        //      style:          JSON-Object 类型值，默认为 null；表示要附加到该菜单项的样式；
        //      handler:    表示菜单项的点击事件，该事件函数格式为 function(e, item, menu, grid, field)，其中 this 指向菜单项本身
        //  备注：具体格式参考 easyui-datagrid 的 toolbar 属性为 Array 对象类型的格式；
        headerContextMenu: null,

        //  扩展 easyui-datagrid 的自定义属性，该属性表示表列头过滤菜单中显示的数据行数的个数，超过该个数的其他数据行将不显示；
        //  Number 类型值，默认为 10 。
        headerFilterMenuLength: 10
    };

    var methods = $.fn.datagrid.extensions.methods = {


    };


    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 扩展
* jeasyui.extensions.datagrid.rowContext.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2017-12-27
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.menu.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function ($) {

    $.util.namespace("$.fn.datagrid.extensions");

    function getTrIndex(tr) {
        if (!tr) {
            return -1;
        }
        tr = $.util.isJqueryObject(tr) ? tr : $(tr);
        var attr = tr.attr("datagrid-row-index");
        return (attr == null || attr == undefined || attr == "") ? -1 : window.parseInt(attr, 10);
    }

    function getRow(target, index) {
        var t = $(target),
            rows = t.datagrid("getRows");
        return rows ? rows[index] : undefined;
    }

    function getRowMenuItems(t, opts, e, index, row) {
        var menuItems = [],
            defaultMenuItems = [],
            args = [t[0], index, row];

        if (opts.refreshMenu) {
            $.array.merge(defaultMenuItems, $.fn.datagrid.extensions.refreshMenus);
        }
        if (opts.pagingMenu != null && opts.pagingMenu != undefined && (opts.pagingMenu == true || !opts.pagingMenu.disabled)) {
            $.array.merge(defaultMenuItems,
                defaultMenuItems.length ? "-" : [],
                opts.pagingMenu.submenu ? $.fn.datagrid.extensions.pagingRootMenus : $.fn.datagrid.extensions.pagingMenus);
        }

        if ($.array.likeArrayNotString(opts.rowContextMenu)) {
            $.array.merge(menuItems, menuItems.length ? "-" : [], opts.rowContextMenu);
        }
        if (defaultMenuItems.length) {
            $.array.merge(menuItems, menuItems.length ? "-" : [], defaultMenuItems);
        }

        return $.easyui.parseMenuItems(menuItems, args);
    }

    function initRowContextMenu(t, opts) {
        t.datagrid("getPanel").panel("body").delegate("tr.datagrid-row", "contextmenu.datagrid-extensions", function (e) {
            var index = getTrIndex(this);
            if (index == -1) {
                return;
            }
            if (opts.selectOnRowContextMenu) {
                t.datagrid("selectRow", index);
            }
            if (opts.enableRowContextMenu) {
                e.preventDefault();
                if ($.type(opts.pagingMenu) == "object") {
                    opts.pagingMenu = $.union(opts.pagingMenu, { disabled: false, submenu: true });
                }
                var row = getRow(t[0], index),
                    menuItems = getRowMenuItems(t, opts, e, index, row);
                $.easyui.showMenu({ items: menuItems, left: e.pageX, top: e.pageY, event: e });
            }
        });
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initRowContextMenu(t, opts);
    }


    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this, [
                            {
                                selectOnRowContextMenu: "boolean",
                                enableRowContextMenu: "boolean",
                                refreshMenu: "boolean",
                            }
                        ]), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);

    function disabledPrevPage(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options,
            pager = t.datagrid("getPager");
        if (!opts.pagination || !pager || !pager.length) {
            return true;
        }
        var popts = pager.pagination("options");
        return popts.pageNumber <= 1;
    }

    function disabledNextPage(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options,
            pager = t.datagrid("getPager");
        if (!opts.pagination || !pager || !pager.length) {
            return true;
        }
        var popts = pager.pagination("options"),
            pageCount = Math.ceil(parseFloat(popts.total) / parseFloat(popts.pageSize));
        return popts.pageNumber >= pageCount;
    }

    function selectFirstPage(target) {
        var disabled = disabledPrevPage(target);
        if (disabled) {
            return;
        }
        $(target).datagrid("getPager").pagination("select", 1);
    }

    function selectPrevPage(target) {
        var disabled = disabledPrevPage(target);
        if (disabled) {
            return;
        }
        var pager = $(target).datagrid("getPager"),
            popts = pager.pagination("options");
        pager.pagination("select", popts.pageNumber - 1);
    }

    function selectNextPage(target) {
        var disabled = disabledNextPage(target);
        if (disabled) {
            return;
        }
        var pager = $(target).datagrid("getPager"),
            popts = pager.pagination("options");
        pager.pagination("select", popts.pageNumber + 1);
    }

    function selectLastPage(target) {
        var disabled = disabledNextPage(target);
        if (disabled) {
            return;
        }
        var pager = $(target).datagrid("getPager"),
            popts = pager.pagination("options"),
            pageCount = Math.ceil(parseFloat(popts.total) / parseFloat(popts.pageSize));
        pager.pagination("select", pageCount);
    }

    $.fn.datagrid.extensions.refreshMenus = [
        {
            text: "刷新当前页", iconCls: "pagination-load",
            disabled: function (e, menuItem, menu, target, index, row) {
                var t = $(target),
                    state = $.data(target, "datagrid"),
                    opts = state.options;
                return !opts.refreshMenu ? true : false;
            },
            handler: function (e, menuItem, menu, target, index, row) {
                $(target).datagrid("reload");
            }
        }
    ];
    $.fn.datagrid.extensions.pagingMenus = [
        {
            text: "首页", iconCls: "pagination-first",
            disabled: function (e, menuItem, menu, target, index, row) {
                return disabledPrevPage(target);
            },
            handler: function (e, menuItem, menu, target, index, row) {
                selectFirstPage(target);
            }
        },
        {
            text: "上一页", iconCls: "pagination-prev",
            disabled: function (e, menuItem, menu, target, index, row) {
                return disabledPrevPage(target);
            },
            handler: function (e, menuItem, menu, target, index, row) {
                selectPrevPage(target);
            }
        },
        {
            text: "下一页", iconCls: "pagination-next",
            disabled: function (e, menuItem, menu, target, index, row) {
                return disabledNextPage(target);
            },
            handler: function (e, menuItem, menu, target, index, row) {
                selectNextPage(target);
            }
        },
        {
            text: "末页", iconCls: "pagination-last",
            disabled: function (e, menuItem, menu, target, index, row) {
                return disabledNextPage(target);
            },
            handler: function (e, menuItem, menu, target, index, row) {
                selectLastPage(target);
            }
        }
    ];
    $.fn.datagrid.extensions.pagingRootMenus = [
        {
            text: "翻页", iconCls: "",
            disabled: function (e, menuItem, menu, target, index, row) {
                var state = $.data(target, "datagrid"),
                    opts = state.options;
                return opts.pagingMenu == true || !opts.pagingMenu.disabled ? false : true;
            },
            children: $.fn.datagrid.extensions.pagingMenus
        }
    ];


    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义属性，该属性表示在打开数据行右键菜单时是否触发数据行的 Select 动作；
        //  Boolean 类型值，默认为 false。
        selectOnRowContextMenu: false,

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用 easyui-datagrid 的数据行右键菜单；
        //  Boolean 类型值，默认为 true。
        enableRowContextMenu: true,

        //  扩展 easyui-datagrid 的自定义属性，该属性表示数据行右键菜单，为一个 Array 对象；数组中的每一个元素都具有如下属性:
        //      id:         表示菜单项的 id；
        //      text:       表示菜单项的显示文本；
        //      iconCls:    表示菜单项的左侧显示图标；
        //      disabled:   表示菜单项是否被禁用(禁用的菜单项点击无效)；
        //      hideOnClick:    表示该菜单项点击后整个右键菜单是否立即自动隐藏；
        //      bold:           Boolean 类型值，默认为 false；表示该菜单项是否字体加粗；
        //      style:          JSON-Object 类型值，默认为 null；表示要附加到该菜单项的样式；
        //      handler:    表示菜单项的点击事件，该事件函数格式为 function(e, item, menu, grid, rowIndex, row)，其中 this 指向菜单项本身
        //  备注：具体格式参考 easyui-datagrid 的 toolbar 属性为 Array 对象类型的格式；
        rowContextMenu: null,

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用数据行右键菜单中的“翻页”菜单项的功能；
        //  该属性可以定义为以下类型：
        //      Boolean 类型值，表示是否启用右键菜单中的“翻页”菜单项功能，默认为 true。
        //      JSON-Object 类型，该 JSON-Object 可以包含如下属性：
        //          disabled:   Boolean 类型值，表示是否禁用右键菜单中的“翻页”菜单项功能，默认为 false；
        //          submenu:    表示这四个菜单项是否以子菜单方式呈现，默认为 true；
        //  备注：当 enableRowContextMenu 属性设置为 true 时，该属性才有效。
        pagingMenu: { submenu: false },

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用数据行右键菜单中的“刷新当前页”菜单项的功能；
        //  Boolean 类型值，默认为 true。
        //  备注：当 enableRowContextMenu 属性设置为 true 时，该属性才有效。
        refreshMenu: true
    };

    var methods = $.fn.datagrid.extensions.methods = {


    };


    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 扩展
* jeasyui.extensions.datagrid.groupSummary.js
* 开发 真真
* 由 落阳 整理及完善
* 最近更新：2016-05-30
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.getColumnInfo.js
*   3、jeasyui.extensions.datagrid.columnToggle.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function ($) {

    $.util.namespace("$.fn.datagrid.extensions");

    function getTrIndex(tr) {
        if (!tr) {
            return -1;
        }
        tr = $.util.isJqueryObject(tr) ? tr : $(tr);
        var attr = tr.attr("datagrid-row-index");
        return (attr == null || attr == undefined || attr == "") ? -1 : window.parseInt(attr, 10);
    }

    function getVisibleRows(target) {
        var t = $(target),
            rows = t.datagrid("getRows"),
            p = t.datagrid("getPanel"),
            indexes = [];
        p.find("div.datagrid-view div.datagrid-body table.datagrid-btable:first tr.datagrid-row:not(.datagrid-row-hidden)").each(function () {
            var index = getTrIndex(this);
            if (index != -1) {
                indexes.push(index);
            }
        });
        return (!rows || !rows.length || !indexes.length)
            ? []
            : $.array.map(indexes, function (i) {
                return rows[i];
            });
    }


    // 分组汇总菜单
    $.fn.datagrid.extensions.groupSummaryMenus = [
        {
            text: "分组汇总", iconCls: "icon-standard-application-side-tree",
            handler: function (e, menuItem, menu, target, field) {
                showGroupSummaryDialog(target, field);
            }
        }
    ];
    //可分组汇总的字段显示窗口
    function showGroupSummaryDialog(target, field) {
        var t = $(target), opts = t.datagrid("options"),
            oriCols = $.extend(true, [], t.datagrid("getColumnOptions", "all"));
        var data = [], count = 0;
        //可选择的列数据初始化
        $.each(oriCols, function (index, item) {
            if (!item.groupable || !item.field || !item.title) { return; }
            data.push({ id: index, field: item.field, title: item.title, width: item.width });
        });
        //弹框
        var d = top.$("<div />").appendTo($("body")).dialog({
            title: "分组汇总配置",
            iconCls: "icon-standard-application-view-detail",
            height: 360,
            width: 520,
            modal: true,
            topMost : true,
            resizable: true,
            content:
            '<div id="groupSummaryLayout">' +
                '<div region="west" border="false" style="width:260px;padding:4px 2px 4px 4px;">' +
                    '<table id="groupSummaryAllColumnsGrid" />' +
                '</div>' +
                '<div region="center" border="false" style="padding:4px 4px 4px 2px;">' +
                    '<table id="groupSummarySelectColumnsGrid" />' +
                '</div>' +
            '</div>',
            buttons: [
                {
                    text: "确定", iconCls: "icon-ok", handler: function () {
                        var rows = top.$("#groupSummarySelectColumnsGrid").datagrid("getRows");
                        if (rows.length > 0) {
                            setTimeout(function () {
                            	 parseGroupSummaryInvoke(t, opts, rows, oriCols);
                            }, 10);
                        }
                        else {top.$.messager.alert('提示', '缺少分组字段!', 'info');}
                    }
                },
                {
                    text: "关闭", iconCls: "icon-cancel", handler: function () {
                        d.dialog("destroy");
                    }
                }
            ]
        });
        //重写dialog的x按钮事件，以确保关闭dialog时会销毁dialog
        var toolbutton = d.dialog("header").find(".panel-tool a.panel-tool-close");
        toolbutton.click(function () { d.dialog("destroy"); });
        //布局初始化
        top.$("#groupSummaryLayout").layout({ fit: true });
        //待选表格
        top.$("#groupSummaryAllColumnsGrid").datagrid({
            title: "字段列表(单击添加)",
            nowrap: false, rownumbers: true,
            fit: true, singleSelect: true, idField: "id",
            data: data,
            columns: [[
                { title: '字段名称', field: 'title', width: 200, align: "center" }
            ]],
            onClickRow: function (rowIndex, rowData) {
                var rows = top.$("#groupSummarySelectColumnsGrid").datagrid("getRows");
                if (!$.array.contains(rows, rowData, function (a, b) { return a.id == b.id; })) {
                	top.$("#groupSummarySelectColumnsGrid").datagrid("appendRow", rowData);
                }
            },
            enableHeaderContextMenu: false,
            enableHeaderClickMenu: false,
            enableGroupSummary: false
        });
        //已选表格
        top.$("#groupSummarySelectColumnsGrid").datagrid({
            title: "已选字段(单击移除)",
            nowrap: false, rownumbers: true,
            fit: true, singleSelect: true, idField: "id",
            columns: [[
                { title: '字段名称', field: 'title', width: 200, align: "center" }
            ]],
            onClickRow: function (rowIndex, rowData) {
            	top.$("#groupSummarySelectColumnsGrid").datagrid("deleteRow", rowIndex);
            },
            enableHeaderContextMenu: false,
            enableHeaderClickMenu: false,
            enableGroupSummary: false
        });
    }
    function parseGroupSummaryInvoke(t, opts, selfCols, oriCols) {
        oriCols = $.extend(true, [], oriCols);
        var values = [], level = 0;
        var mode = $.util.isBoolean(opts.enableGroupSummary) ? "local" : opts.enableGroupSummary.mode;
        if (mode == "local") {
            var rows = $.extend(true, [], getVisibleRows(t[0]));
            var data = parseGroupSummaryInitRows(t, opts, values, rows, oriCols, selfCols, level);
            parseGroupSummaryLoadData(oriCols, selfCols, data);
        } else {
            if ($.string.isNullOrWhiteSpace(opts.url)) {
            	top.$.messager.alert("操作提醒", "远程数据地址未设置，无法进行分组汇总。"); return;
            }
            //组装参数
            var queryParams = $.extend({}, opts.queryParams);
            if (opts.pagination) {
                //页码为0表示查询所有数据，这需要与后台协定好
                $.extend(queryParams, { page: 0, rows: opts.pageSize });
            }
            if (opts.sortName) {
                $.extend(queryParams, { sort: opts.sortName, order: opts.sortOrder });
            }
            opts.loader.call(t[0], queryParams, function (rows) {
                if ($.isPlainObject(rows)) { rows = rows.rows; }
                var data = parseGroupSummaryInitRows(t, opts, values, rows, oriCols, selfCols, level);
                parseGroupSummaryLoadData(oriCols, selfCols, data);
            }, function () {
                //发生异常时
            });
        }
    }
    //数据组装
    function parseGroupSummaryInitRows(t, opts, pValues, rows, oriCols, selfCols, level) {
        if (selfCols.length <= level) {
            //如果超出层级范围则添加明细数据
            return parseGroupSummaryInitData(pValues, rows, selfCols, level);
        }
        var data = [], selfCol = selfCols[level], len = rows.length;
        var ignoreFormatter = true;
        if ($.isPlainObject(opts.enableGroupSummary)) {
            ignoreFormatter = opts.enableGroupSummary.ignoreFormatter;
        }
        for (var i = 0; i < len; i++) {
            var bit = true, value = rows[i][selfCol.field] || "空白";
            //判断是否满足向上逐级条件
            for (var v = 0; v < pValues.length && bit; v++) {
                var stepValue = rows[i][pValues[v].field] || "空白";
                if (stepValue != pValues[v].value) {
                    bit = false;
                }
            }
            if (bit) {
                //判断是否存在分组
                for (var d = 0; d < data.length && bit; d++) {
                    if (data[d]["groupSummaryName"] == value) {
                        bit = false;
                    }
                }
            }

            if (bit) {
                //写入分组数据
                var row = {};
                var values = $.extend(true, [], pValues);
                values.push({ field: selfCol.field, value: value });
                //递归
                row["children"] = parseGroupSummaryInitRows(t, opts, values, rows, oriCols, selfCols, level + 1);
                parseGroupSummaryInvokeSum(t, row, ignoreFormatter, oriCols, selfCols);
                row["groupSummaryID"] = "g_" + level + "_" + i;
                row["groupSummaryName"] = value;
                row["state"] = "closed";
                data.push(row);
            }
        }
        return data;
    }
    //装载明细
    function parseGroupSummaryInitData(pValues, rows, selfCols, level) {
        var data = [];
        for (var i = 0; i < rows.length; i++) {
            var bit = true;
            //向上逐级条件判断
            for (var v = 0; v < pValues.length && bit; v++) {
                var stepValue = rows[i][pValues[v].field] || "空白";
                if (stepValue != pValues[v].value) {
                    bit = false; break;
                }
            }
            if (bit) {
                var row = $.extend(true, {}, rows[i]);
                row["groupSummaryID"] = "g_" + level + "_" + i;
                row["groupSummaryName"] = "明细";
                data.push(row);
            }
        }
        return data;
    };
    //分组汇总计算
    function parseGroupSummaryInvokeSum(t, row, ignoreFormatter, oriCols, selfCols) {
        var rowIndex = t.datagrid("getRowIndex", row);
        $.each(oriCols, function (i, c) {
            var bit = true;
            //分组列不做汇总
            for (var s = 0; s < selfCols.length && bit; s++) {
                if (selfCols[s].field == c.field) {
                    bit = false;
                }
            }
            if (bit) {
                var temp = 0;
                //汇总计算
                var len = row["children"].length;
                for (var n = 0; n < len; n++) {
                    if (!c.calcable) {
                        temp = ""; break;
                    }
                    var value = row["children"][n][c.field],
                        realValue = ignoreFormatter ? value : (((n != (len - 1)) && c.formatter && $.isFunction(c.formatter)) ? c.formatter.call(t[0], value, row, rowIndex) : value);
                    if ($.type(realValue) == "number") {
                        temp += realValue;
                    }
                    else if ($.type(value) == "number") {
                        temp += value;
                    }
                    else { temp = ""; break; }
                }
                row[c.field] = temp;
            }
        });
    };
    //分组汇总载入数据
    function parseGroupSummaryLoadData(oriCols, selfCols, rows) {
        //弹窗
        var d = top.$("<div />").appendTo($("body")).dialog({
            title: "分组汇总",
            modal: true,
            width: $(window).width() - 20,
            height: $(window).height() - 20,
            content: '<table id="groupSummaryGrid" />',
            buttons: [
                {
                    text: "关闭", iconCls: "icon-cancel", handler: function () {
                        d.dialog("destroy");
                    }
                }
            ]
        });
        //重写dialog的x按钮事件，以确保关闭dialog时会销毁dialog
        var toolbutton = d.dialog("header").find(".panel-tool a.panel-tool-close");
        toolbutton.click(function () { d.dialog("destroy"); });

        var title = "层级：", width = 40, rowspan = 1;
        for (var i = 0; i < selfCols.length; i++) {
            if (i > 0) { title += " > "; }
            title += selfCols[i].title;
            width = selfCols[i].width > width ? selfCols[i].width : width;
            $.each(oriCols, function (index, c) {
                //隐藏分组列
                if (c.field == selfCols[i].field) {
                    c.hidden = true;
                }
                //跨行表头支持
                if (c.rowspan) {
                    rowspan = c.rowspan > rowspan ? c.rowspan : rowspan;
                }
            });
        }
        //树形列添加
        oriCols.insert(0, {
            width: width + (selfCols.length * 50), align: "left",
            title: title, rowspan: rowspan,
            field: "groupSummaryName"
        });
        var tg = top.$("#groupSummaryGrid").treegrid({
            nowrap: false, border: false,
            fit: true, singleSelect: true,
            remoteSort: false,
            idField: "groupSummaryID",
            treeField: "groupSummaryName",
            columns: [oriCols], data: rows,
            enableHeaderContextMenu: false,
            enableHeaderClickMenu: false,
            enableGroupSummary: false
        });
    };




    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

    }

    function beforeInitialize(opts) {
        if (opts.enableGroupSummary == undefined) {
            opts.enableGroupSummary = { enable: true, mode: "local", ignoreFormatter: true };
        }
        else if ($.isPlainObject(opts.enableGroupSummary)) {
            opts.enableGroupSummary.enable = opts.enableGroupSummary.enable == undefined ? true : opts.enableGroupSummary.enable;
            opts.enableGroupSummary.mode = opts.enableGroupSummary.mode == undefined ? "local" : (["local", "remote"].contains(opts.enableGroupSummary.mode) ? opts.enableGroupSummary.mode : "local");
            opts.enableGroupSummary.ignoreFormatter = opts.enableGroupSummary.ignoreFormatter == undefined ? true : opts.enableGroupSummary.ignoreFormatter;
        }

        if (($.util.isBoolean(opts.enableGroupSummary) && opts.enableGroupSummary) || ($.isPlainObject(opts.enableGroupSummary) && opts.enableGroupSummary.enable)) {
            if (!$.isArray(opts.headerContextMenu)) {
                opts.headerContextMenu = [];
            }
            $.array.merge(opts.headerContextMenu, $.fn.datagrid.extensions.groupSummaryMenus);
        }
        //合并columnOptions
        if (opts.frozenColumns) {
            $.each(opts.frozenColumns, function (ii, cc) {
                $.each(cc, function (i, c) {
                    $.union(c, $.fn.datagrid.extensions.columnOptions);
                });
            });
        }
        if (opts.columns) {
            $.each(opts.columns, function (ii, cc) {
                $.each(cc, function (i, c) {
                    $.union(c, $.fn.datagrid.extensions.columnOptions);
                });
            });
        }
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this), options);
            if (!isInited) { beforeInitialize(opts); }
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);


    var columnOptions = {

        // 表示该列是否可分组，其值可以是 Boolean 类型；
        // 默认为 true。
        // 该属性用于在“列分组”时判定
        groupable: true,

        // 表示该列是否可计算，其值可以是 Boolean 类型；
        // 默认为 false。
        // 该属性用于在“汇总计算”时使用。
        calcable: false
    };
    if ($.fn.datagrid.extensions.columnOptions) {
        $.extend($.fn.datagrid.extensions.columnOptions, columnOptions);
    }
    else {
        $.fn.datagrid.extensions.columnOptions = columnOptions;
    }


    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用分组汇总按钮菜单功能；该属性可以是以下两种数据类型：
        //      1、JSON-Object 类型值，表示分组汇总的参数，该对象类型参数包含如下属性：
        //              enable:      表示是否启用分组汇总按钮菜单功能，默认为 true ；
        //              mode:        表示要分组汇总的数据是本地数据还是远程数据，其值可以是 local、remote，默认为 local ；
        //              ignoreFormatter:     表示在统计时是否忽略 columns 中设置的 formatter 回调函数，默认为 true ；
        //                  注意，如果可计算的列（calcable:true）通过 formatter 后返回的值不是 number 类型，即使 ignoreFormatter 设置为 true，也将忽略该 formatter 效果。
        //      2、Boolean 类型值，表示是否启用分组汇总按钮菜单功能，默认为 false。 
        enableGroupSummary: true
    };

    var methods = $.fn.datagrid.extensions.methods = {


    };


    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.updateColumn.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-25
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var setColumnTitle = function (target, param) {
        if (param && param.field && param.title) {
            var t = $(target), colOpts = t.datagrid("getColumnOption", param.field),
                field = param.field, title = param.title,
                panel = t.datagrid("getPanel"),
                td = panel.find("div.datagrid-view div.datagrid-header tr.datagrid-header-row td[field=" + field + "]");
            if (td.length) { td.find("div.datagrid-cell span:first").html(title); colOpts.title = title; }
        }
    };

    var setColumnWidth = function (target, param) {
        if (param && param.field && param.width && $.isNumeric(param.width)) {
            var state = $.data(target, "datagrid"),
                t = $(target),
                opts = t.datagrid("options"),
                colOpts = t.datagrid("getColumnOption", param.field),
                field = param.field, width = param.width,
                cell = t.datagrid("getPanel").find("div.datagrid-view div.datagrid-header tr.datagrid-header-row td[field=" + field + "] div.datagrid-cell");
            if (cell.length) {
                
                var diff = $.string.isNullOrWhiteSpace(cell[0].style.width) ? (colOpts.width - colOpts.boxWidth) : cell._outerWidth() - parseInt(cell[0].style.width);
                cell.css("height", "");
                colOpts.width = width; 
                colOpts.boxWidth = width - diff;
                colOpts.auto = undefined;
                cell.width(colOpts.boxWidth);
                t.datagrid("fixColumnSize", field);
                t.datagrid("fitColumns");
                opts.onResizeColumn.call(target, field, width);
            }
        }
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；设置 easyui-datagrid 中列的标题；参数 param 是一个 JSON-Object 对象，包含如下属性：
        //      field: 列字段名称；
        //      title: 列的新标题；
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        setColumnTitle: function (jq, param) { return jq.each(function () { setColumnTitle(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；设置 easyui-datagrid 中列的宽度；参数 param 是一个 JSON-Object 对象，该 JSON 对象定义如下属性：
        //      field: 要设置列宽的的列 field 值；
        //      width: 要设置的列宽度，Number 类型值；
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        setColumnWidth: function (jq, param) { return jq.each(function () { setColumnWidth(this, param); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.getDom.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-02
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var getRowDom = function (target, index) {
        if (!$.isNumeric(index) || index < 0) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel");
        return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "]");
    };

    var getColumnDom = function (target, param) {
        if ($.string.isNullOrEmpty(param)) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel"),
            isObject = !$.string.isString(param),
            field = isObject ? param.field : param,
            header = isObject ? param.header : false,
            dom = panel.find("div.datagrid-view tr.datagrid-row td[field=" + field + "]");
        if (header) { dom = dom.add(panel.find("div.datagrid-view tr.datagrid-header-row td[field=" + field + "]")); }
        return dom;
    };

    var getCellDom = function (target, pos) {
        if (!pos || !pos.field || !$.isNumeric(pos.index) || pos.index < 0) { return $(); }
        var t = $(target), tr = t.datagrid("getRowDom", pos.index);
        return tr.find("td[field=" + pos.field + "] .datagrid-cell");
    };

    var getCellHtml = function (target, pos) {
        var td = getCellDom(target, pos);
        return td && td.length ? td.html() : undefined;
    };

    var getCellText = function (target, pos) {
        var td = getCellDom(target, pos);
        return td && td.length ? td.text() : undefined;
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定行的 DOM-jQuery 对象元素集合；该函数定义如下参数：
        //      index: 表示要获取的 DOM-Jquery 对象元素集合所在当前页的行索引号；
        //  返回值：如果当前页存在 index 指示的行，则返回该行的 DOM-jQuery 对象集合，该集合中包含的 DOM 节点级别为一组 tr class="datagrid-row" 对象；
        //          否则返回一个空的 jQuery 对象。
        getRowDom: function (jq, index) { return getRowDom(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定列的 DOM-jQuery 元素对象；该函数定义如下参数：
        //      param: 该参数可以定义以下类型：
        //          String 类型：表示要获取的 DOM-jQuery 元素所在的列的 field 名；
        //          JSON-Object 类型：如果定义为该类型，则该参数定义如下属性：
        //              field:  表示要获取的 DOM-jQuery 元素所在的列的 field 名；
        //              header: Boolean 类型值，默认为 false，表示返回的 DOM-jQuery 对象中是否包含 field 表示的列的表头；
        //  返回值：如果当前页存在 field 值指定的列，则返回该列中指定行的 DOM-jQuery 对象，该对象中包含的 DOM 节点级别为一个 td[field=field] 对象；
        //          否则返回一个空的 jQuery 对象。
        //          如果 param 参数定义为 JSON-Object 类型，且 param.header = true，则返回的 DOM-jQuery 对象中将会包含列的表头元素；
        //          如果 param 参数定义为 String 类型或者即使定义为 JSON-Object 类型但 param.header = false，则返回的 DOM-jQuery 对象中不包含列的表头元素。
        getColumnDom: function (jq, param) { return getColumnDom(jq[0], param); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定单元格的 Dom-jQuery 对象元素；该函数定义如下参数：
        //      pos：表示单元格的位置，为一个 JSON-Object 对象，该 JSON 定义如下属性：
        //          field:  表示要获取的单元格位于哪个列；
        //          index:  表示要获取的单元格位于哪个行的行索引号，从 0 开始；
        //  返回值：如果当前页存在指定列的指定行，则返回该列中指定行的 DOM-jQuery 对象，该对象中包含的 DOM 节点级别为一个 div class="datagrid-cell" 对象；
        //          否则返回一个空的 jQuery 对象。
        getCellDom: function (jq, pos) { return getCellDom(jq[0], pos); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定单元格的显示数据(经过 formatter 格式化后的显示数据)；该函数定义如下参数：
        //  pos：表示单元格的位置，为一个 JSON-Object 对象，该 JSON 定义如下属性：
        //          field:  表示要获取的单元格位于哪个列；
        //          index:  表示要获取的单元格位于哪个行的行索引号，从 0 开始；
        //  返回值：如果当前页存在指定列的指定行，则返回该列中指定行的单元格的显示数据(经过 formatter 格式化后的显示数据)；否则返回 undefined。
        getCellHtml: function (jq, pos) { return getCellHtml(jq[0], pos); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定单元格的显示文本(经过 formatter 格式化后的显示文本)；该函数定义如下参数：
        //  pos：表示单元格的位置，为一个 JSON-Object 对象，该 JSON 定义如下属性：
        //          field:  表示要获取的单元格位于哪个列；
        //          index:  表示要获取的单元格位于哪个行的行索引号，从 0 开始；
        //  返回值：如果当前页存在指定列的指定行，则返回该列中指定行的单元格的显示文本(经过 formatter 格式化后的显示文本)；否则返回 undefined。
        getCellText: function (jq, pos) { return getCellText(jq[0], pos); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.getRowData.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-01
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var getRowData = function (target, index) {
        if (!$.isNumeric(index) || index < 0) { return undefined; }
        var t = $(target), rows = t.datagrid("getRows");
        return rows[index];
    };

    var getNextRow = function (target, index) {
        return getRowData(target, index + 1);
    };

    var getPrevRow = function (target, index) {
        return getRowData(target, index - 1);
    };

    var popRow = function (target, index) {
        if (!$.isNumeric(index) || index < 0) { return undefined; }
        var t = $(target), rows = t.datagrid("getRows"), row = rows[index];
        if (row) { t.datagrid("deleteRow", index); }
        return row;
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定行的 rowData；该函数定义如下参数：
        //      index: 表示要获取的 rowData 所在当前页的行索引号，从 0 开始；
        //  返回值：如果当前页存在 index 指示的行，则返回该行的行数据对象（JSON Object 格式）；否则返回 undefined。
        getRowData: function (jq, index) { return getRowData(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；获取指定行的下一行数据；该方法的参数 index 表示指定行的行号(从 0 开始)；
        //  返回值：返回指定行的下一行数据，返回值是一个 JSON-Object 对象；
        //      如果指定的行没有下一行数据 (例如该行为最后一行的情况下)，则返回 undefined。
        getNextRow: function (jq, index) { return getNextRow(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；获取指定行的上一行数据；该方法的参数 index 表示指定行的行号(从 0 开始)；
        //  返回值：返回指定行的上一行数据，返回值是一个 JSON-Object 对象；
        //      如果指定的行没有上一行数据 (例如该行为第一行的情况下)，则返回 undefined。
        getPrevRow: function (jq, index) { return getPrevRow(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；从 easyui-datagrid 当前页中删除指定的行，并返回该行数据；
        //  该方法的参数 index 表示指定行的行号(从 0 开始)；
        //  返回值：返回 index 所表示的行的数据，返回值是一个 JSON-Object 对象；
        //      如果不存在指定的行(例如 easyui-datagrid 当前页没有数据或者 index 超出范围)，则返回 undefined。
        popRow: function (jq, index) { return popRow(jq[0], index); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);
  /**
   * jQuery EasyUI 1.4.3
   * Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
   *
   * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
   * To use it on other terms please contact us at info@jeasyui.com
   * http://www.jeasyui.com/license_commercial.php
   *
   * jQuery EasyUI datagrid 组件扩展
   * jeasyui.extensions.datagrid.tooltip.js
   * 开发 流云
   * 由 落阳 整理
   * 最近更新：2015-12-16
   *
   * 依赖项：
   *   1、jquery.jdirk.js
   *   2、jeasyui.extensions.datagrid.getDom.js
   *   3、jeasyui.extensions.datagrid.getColumnInfo.js
   *   4、jeasyui.extensions.datagrid.getRowData.js
   *
   * Copyright (c) 2015 ChenJianwei personal All rights reserved.
   */
  (function () {

      $.util.namespace("$.fn.datagrid.extensions");

      var _originalMethod = {};

      $.extend(_originalMethod, {

          beginEdit: $.fn.datagrid.methods.beginEdit
      });

      function getTrIndex(tr) {
          if (!tr) {
              return -1;
          }
          tr = $.util.isJqueryObject(tr) ? tr : $(tr);
          var attr = tr.attr("datagrid-row-index");
          return (attr == null || attr == undefined || attr == "") ? -1 : window.parseInt(attr, 10);
      }



      function initializeExtensions(target) {
          var t = $(target),
              state = $.data(target, "datagrid"),
              opts = state.options;

          initRowMouseEvent(t, opts);
      }

      function initRowMouseEvent(t, opts) {
          var target = t[0];
          t.datagrid("getPanel").panel("body").delegate("tr.datagrid-row", {
              "mouseenter.datagrid-extensions": function (e) {
                  var tr = $(this);
                  if (tr.is(".datagrid-row-editing")) { return; }
                  var index = getTrIndex(tr);
                  if (index == -1) { return; }
                  var row = t.datagrid("getRowData", index);
                  showRowTooltip(target, index, t, opts, row, tr, e);
              },
              "mouseleave.datagrid-extensions": function () {
                  var tr = $(this),
                      index = getTrIndex(tr);
                  if (index == -1) { return; }
                  hideRowTooltip(target, index, tr);
              }
          });
      }

      function showRowTooltip(target, index, t, opts, row, tr, e) {
          t = t || $(target);
          opts = opts || $.data(target, "datagrid").options;
          row = row || t.datagrid("getRowData", index);
          tr = tr || t.datagrid("getRowDom", index);
          if (opts.rowTooltip) {
              var content = $.isFunction(opts.rowTooltip) ? opts.rowTooltip.call(target, index, row) : getRowTooltipContent(target, index, row);
              tr.each(function () {
                  if (!$.data(this, "tooltip")) {
                      $(this).tooltip({
                          content: content,
                          trackMouse: true,
                          showDelay: opts.tooltipDelay
                      }).tooltip("show");
                  }
              });
          } else {
              tr.children("td[field]").each(function () {
                  var td = $(this),
                      field = td.attr("field"),
                      copts = t.datagrid("getColumnOption", field);
                  if (!copts || !copts.tooltip) { return; }
                  if (!$.data(td[0], "tooltip")) {
                      var content = $.isFunction(copts.tooltip) ? copts.tooltip.call(target, row[field], index, row) : t.datagrid("getCellHtml", { field: field, index: index });
                      td.tooltip({
                          content: content,
                          trackMouse: true,
                          showDelay: opts.tooltipDelay
                      });
                  }
                  if (e && e.target) {
                      if (td[0] == e.target || $.contains(t[0], e.target)) {
                          td.tooltip("show");
                      }
                  } else {
                      td.tooltip("show");
                  }
              });
          }
      }

      function getRowTooltipContent(target, index, row) {
          var t = $(target), cols = t.datagrid("getColumnOptions", "all"),
              content = $("<table style='padding: 5px;'></table>");
          $.each(cols, function (i, copts) {
              if (!copts || !copts.field || !copts.title) { return; }
              var text = t.datagrid("getCellHtml", { field: copts.field, index: index });
              content.append("<tr style='height: 20px;'><td style='text-align: right; width: 150px;'>" + copts.title + ":</td><td style='width: 250px;'>" + text + "</td></tr>");
          });
          return content;
      }

      function hideRowTooltip(target, index, tr) {
          tr = tr || $(target).datagrid("getRowDom", index);
          tr.tooltip("destroy").children("td[field]").each(function () {
              $(this).tooltip("destroy");
          });
      }

      function beginEdit(target, index) {
          var t = $(target),
              ret = _originalMethod.beginEdit.call(t, t, index),
              editing = t.datagrid("isEditing", index);
          if (!editing) {
              return;
          }
          hideRowTooltip(target, index);
          return ret;
      }



      var _datagrid = $.fn.datagrid;
      $.fn.datagrid = function (options, param) {
          if (typeof options == "string") {
              return _datagrid.apply(this, arguments);
          }
          options = options || {};
          return this.each(function () {
              var jq = $(this),
                  isInited = $.data(this, "datagrid") ? true : false,
                  opts = isInited ? options : $.extend({},
                      $.fn.datagrid.parseOptions(this),
                      $.parser.parseOptions(this, [
                          {
                              tooltipDelay: "number"
                          },
                          {
                              rowTooltip: "boolean"
                          }
                      ]), options);
              _datagrid.call(jq, opts, param);
              if (!isInited) {
                  initializeExtensions(this);
              }
          });
      };
      $.union($.fn.datagrid, _datagrid);


      var methods = {

          //  重写 easyui-datagrid 的原生方法 beginEdit ，以支持自定义属性 rowTooltip 和列属性 tooltip 的扩展功能；
          beginEdit: function (jq, index) { return jq.each(function () { beginEdit(this, index); }); }
      };

      var defaults = {

          //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用行数据的 tooltip 功能；
          //  该属性可以是一个 Boolean 类型值；也可以是一个签名为 function(rowIndex, rowData) 的回调函数；
          //  如果该参数是一个回调函数，则表示启用行数据的 tooltip 功能，并且该函数的返回值为 tooltip 的 content 值。
          //  默认为 Boolean 类型，值为 false。
          //  注意：当启用该配置属性后，所有列的 tooltip 属性就会自动失效。
          rowTooltip: false,

          // 扩展 easyui-datagrid 的自定义属性，该属性表示 rowTooltip 为 true 或 列的扩展属性 tooltip 为 true 时，显示 tooltip 时的延迟毫秒数；
          // 该属性的值是 Number 类型，默认为 300 。
          tooltipDelay: 300
      };



      //  增加了 easyui-datagrid 中列 columnOption 的部分自定义扩展属性
      var columnOptions = {

          // 表示是否启用该列的 tooptip 效果，其值可以是以下两种类型：
          //      Boolean 类型，表示是否启用该列的 tooltip；
          //      Function 类型，其函数签名为 function (value, rowIndex, rowData)，表示为该列启用 tooltip 的方式；
          //          该回调函数返回一个 String 类型值，表示 tooltip 的 content 内容。
          // 默认为 Boolean 类型，值为 false。
          tooltip: false
      };

      if ($.fn.datagrid.extensions.columnOptions) {
          $.extend($.fn.datagrid.extensions.columnOptions, columnOptions);
      }
      else {
          $.fn.datagrid.extensions.columnOptions = columnOptions;
      }

      if ($.fn.datagrid.extensions.defaults) {
          $.extend($.fn.datagrid.extensions.defaults, defaults);
      } else {
          $.fn.datagrid.extensions.defaults = defaults;
      }

      if ($.fn.datagrid.extensions.methods) {
          $.extend($.fn.datagrid.extensions.methods, methods);
      } else {
          $.fn.datagrid.extensions.methods = methods;
      }


      $.extend($.fn.datagrid.defaults, defaults);
      $.extend($.fn.datagrid.methods, methods);

  })(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.findRow.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-21
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    function findRow(target, param, t, opts, rows) {
        t = t && t.length ? t : $(target);
        opts = opts ? opts : $.data(target, "datagrid").options;
        rows = rows && rows.length ? rows : t.datagrid("getRows");
        var type = $.type(param);
        if (type == "function") {
            return $.array.first(rows, function (row, index) {
                return param.call(target, row, index, rows);
            });
        } else if (type == "object") {
            return opts.idField && (opts.idField in param)
                ? findRowById(param[opts.idField])
                : $.array.first(rows, function (val) { return val == param; });
        } else {
            return findRowById(param);
        }
        function findRowById(id) {
            return $.array.first(rows, function (row) {
                return row[opts.idField] == id;
            });
        }
    }

    function findRows(target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options,
            rows = t.datagrid("getRows");
        if ($.isFunction(param)) {
            return $.array.filter(rows, function (val, index) {
                return param.call(target, val, index, rows);
            });
        } else if ($.array.likeArrayNotString(param)) {
            var array = $.array.map(param, function (val) {
                return findRow(target, val, t, opts, rows);
            });
            return $.array.filter(array, function (val) {
                return val != null && val != undefined;
            });
        } else {
            return [findRow(target, param, t, opts, rows)];
        }
    }

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；查找当前数据页上的行数据，返回的是一个 JSON 对象；参数 param 表示查找的内容；该方法的参数 param 可以是以下三种类型：
        //      待查找的行数据的 idField(主键) 字段值；
        //      待查找的行数据对象 row ，若当前 easyui-datagrid 存在 idField 并且 row 对象中存在 idField 则根据 idField 查找，否则根据 row 对象查找；
        //      function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 function 类型，则 findRow 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则表示找到需要查找的结果，立即停止循环调用并返回该行数据；
        //          如果回调函数始终未返回 true，则该回调函数会一直遍历 rows 直到最后并返回 null。
        //  返回值：返回一个 JSON-Object，表示一个行数据对象；如果未找到相应数据，则返回 null。
        findRow: function (jq, param) { return findRow(jq[0], param); },

        //  扩展 easyui-datagrid 的自定义方法；查找当前数据页上的行数据；该方法的参数 param 可以是以下两种类型：
        //      Function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 Function 类型，则 findRows 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则返回的结果集中将会包含该行数据；
        //          如果该回调函数始终未返回 true，则该方法最终返回一个长度为 0 的数组对象。
        //      Array 类型，数组中的每一项都可以定义为如下类型：
        //          待查找的行数据的 idField(主键) 字段值；
        //          Function 类型；具体回调函数签名参考 findRow 方法中 param 参数为 function 类型时的定义；
        //          当 param 参数定义为 Array 类型时，则 findRows 方法会对数组中的每一项循环调用 findRow 方法，并过滤掉 findRow 方法返回 null 的结果行；
        //      落阳注：param 也可以是一个 idField(主键) 字段值，只是返回数据行时会组装成 Array 数组对象。
        //  返回值：返回一个 Array 数组对象；数组中的每一项都是 JSON-Object 类型，表示一个行数据对象；如果未找到相应数据，则返回一个长度为 0 的数组对象。
        findRows: function (jq, param) { return findRows(jq[0], param); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.moveRow.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-01
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    //  param: { target: number, source: number, point: string("top"/default, "bottom") }
    function moveRow(target, param) {
        if (!param || (param.source == null || param.source == undefined)
            || (param.target == null || param.target == undefined)
            || (param.point != "top" && param.point != "bottom")) {
            return;
        }
        var t = $(target),
            rows = t.datagrid("getRows");
        if (!rows || !rows.length) {
            return;
        }
        var sourceIndex = param.source,
            targetIndex = param.target,
            sourceRow = rows[sourceIndex],
            targetRow = rows[targetIndex];
        if (sourceIndex == targetIndex || sourceRow == undefined || targetRow == undefined) {
            return;
        }
        var state = $.data(target, "datagrid"),
            opts = state.options;
        if ($.isFunction(opts.onBeforeMoveRow) && opts.onBeforeMoveRow.call(target, targetRow, sourceRow, param.point) == false) {
            return;
        }
        t.datagrid("deleteRow", sourceIndex);

        var index = t.datagrid("getRowIndex", targetRow);
        if (param.point == "top") {
            t.datagrid("insertRow", { index: index, row: sourceRow });
        } else {
            rows = t.datagrid("getRows");
            if (index++ >= rows.length) {
                t.datagrid("appendRow", sourceRow);
            } else {
                t.datagrid("insertRow", { index: index, row: sourceRow });
            }
        }
        if ($.isFunction(opts.onMoveRow)) {
            opts.onMoveRow.call(target, targetRow, sourceRow, param.point);
        }
    }

    //  param: { index: number, type: string("up"/default, "down") }
    var shiftRow = function (target, param) {
        var sourceIndex = param.index,
            targetIndex = param.type == "up" ? param.index - 1 : param.index + 1,
            point = param.type == "up" ? "top" : "bottom";
        moveRow(target, {
            source: sourceIndex,
            target: targetIndex,
            point: point
        });
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；移动 easyui-datagrid 中的指定 data-row(数据行) ；该方法的参数 param 为 JSON-Object 类型，包含如下属性定义：
        //      target: 表示目标位置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      source: 表示要移动的 data-row(数据行) 索引号(从 0 开始计数)；
        //      point:  表示移动到目标节点 target 的位置，String 类型，可能的值包括：
        //          "top":      表示移动到目标位置 target 的上一格位置；
        //          "bottom":   表示追加为目标位置 target 的下一格位置；
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        //  备注：该方法会触发移动行数据的相应事件；
        moveRow: function (jq, param) { return jq.each(function () { moveRow(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；移动 easyui-datagrid 中的指定 data-row(数据行) 一行位置；该方法的参数 param 为 JSON-Object 类型，包含如下属性定义：
        //      index: 表示要移动的 data-row(数据行) 索引号(从 0 开始计数)；
        //      type:  表示移动到目标节点 target 的位置，String 类型，可能的值包括：
        //          "up":      表示移动到上一格位置；
        //          "down":   表示移动到下一格位置；
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        //  备注：该方法会触发移动行数据的相应事件；
        shiftRow: function (jq, param) { return jq.each(function () { shiftRow(this, param); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义事件；该事件表示移动 data-row(数据行) 之前触发的动作；该事件回调函数提供如下三个参数：
        //      target: 表示目标位置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      source: 表示要移动的 data-row(数据行) 索引号(从 0 开始计数)；
        //      point:  表示移动到目标节点 target 的位置，String 类型，可能的值包括：
        //          "top":      表示移动到目标位置 target 的上一格位置；
        //          "bottom":   表示追加为目标位置 target 的下一格位置；
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        //  如果该事件函数返回 false，则会立即停止移动数据行操作；
        onBeforeMoveRow: function (target, source, point) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示移动 data-row(数据行) 之后触发的动作；该事件回调函数提供如下三个参数：
        //      target: 表示目标位置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      source: 表示要移动的 data-row(数据行) 索引号(从 0 开始计数)；
        //      point:  表示移动到目标节点 target 的位置，String 类型，可能的值包括：
        //          "top":      表示移动到目标位置 target 的上一格位置；
        //          "bottom":   表示追加为目标位置 target 的下一格位置；
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onMoveRow: function (target, source, point) { }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.operateRow.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-19
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.findRow.js
*   3、jeasyui.extensions.datagrid.getDom.js
*   4、jeasyui.extensions.datagrid.getRowData.js
*   5、jeasyui.extensions.datagrid.moveRow.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    //  param: idField | row | function (row, index, rows)
    function showRow(target, param) {
        var state = $.data(target, "datagrid"),
            t = $(target),
            opts = state.options,
            rows = t.datagrid("getRows");

        var row = t.datagrid("findRow", param),
            index = t.datagrid("getRowIndex", row);
        if (index > -1) {
            $.array.remove(state.hiddenRows, row);
            t.datagrid("getRowDom", index).removeClass("datagrid-row-hidden");
        }
    }

    //  param: idField | row | function (row, index, rows)
    function hideRow(target, param) {
        var state = $.data(target, "datagrid"),
            t = $(target),
            opts = state.options,
            rows = t.datagrid("getRows");

        var row = t.datagrid("findRow", param),
            index = t.datagrid("getRowIndex", row);
        if (index > -1) {
            $.array.attach(state.hiddenRows, row);
            t.datagrid("unselectRow", index).datagrid("uncheckRow", index);
            t.datagrid("getRowDom", index).addClass("datagrid-row-hidden");
        }
    }

    //  param: function (row, index, rows) | array (idField | row | function (row, index, rows)) | boolean (false)
    function hideRows(target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        if (param == true) {
            var rows = t.datagrid("getRows");
            $.array.clear(state.hiddenRows);
            $.array.copy(state.hiddenRows, rows);
            $.each(rows, function (i, n) {
                var rowIndex = t.datagrid("getRowIndex", n);
                if (rowIndex > -1) {
                    t.datagrid("getRowDom", rowIndex).addClass("datagrid-row-hidden");
                }
            });
        } else {
            var array = t.datagrid("findRows", param);
            if (array.length) {
                $.each(array, function (i, n) {
                    hideRow(target, n);
                });
            }
        }
    }

    //  param: function (index, row, rows) | array (idField | row | function (index, row, rows)) | boolean (true)
    function showRows(target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        if (param == true) {
            var rows = t.datagrid("getRows");
            $.array.clear(state.hiddenRows);
            $.each(rows, function (i, n) {
                var rowIndex = t.datagrid("getRowIndex", n);
                if (rowIndex > -1) {
                    t.datagrid("getRowDom", rowIndex).removeClass("datagrid-row-hidden");
                }
            });
        } else {
            var array = t.datagrid("findRows", param);
            if (array.length) {
                $.each(array, function (i, n) {
                    showRow(target, n);
                });
            }
        }
    }

    function getHiddenRows(target) {
        var state = $.data(target, "datagrid");
        return state.hiddenRows;
    }

    function getVisibleRows(target) {
        var state = $.data(target, "datagrid"), t = $(target),
            rows = t.datagrid("getRows"), hiddenRows = state.hiddenRows;

        return $.array.filter(rows, function (val) { return $.array.contains(hiddenRows, val) ? false : true; });
    }




    function setDraggableStatus(source, state) {
        var icon = source.draggable("proxy").find("span.tree-dnd-icon");
        icon.removeClass("tree-dnd-yes tree-dnd-no").addClass(state ? "tree-dnd-yes" : "tree-dnd-no");
    }

    function getTrIndex(tr) {
        if (!tr) {
            return -1;
        }
        tr = $.util.isJqueryObject(tr) ? tr : $(tr);
        var attr = tr.attr("datagrid-row-index");
        return (attr == null || attr == undefined || attr == "") ? -1 : window.parseInt(attr, 10);
    }

    function getEditingRowIndexes(target) {
        var t = $(target),
            p = t.datagrid("getPanel"),
            indexes = [];
        p.find("div.datagrid-view div.datagrid-body table.datagrid-btable:first tr.datagrid-row.datagrid-row-editing").each(function () {
            var index = getTrIndex(this);
            if (index != -1) {
                indexes.push(index);
            }
        });
        return indexes;
    }

    function resetRowDnd(target, index, t, opts, row, tr) {
        t = t || $(target);
        opts = opts || $.data(target, "datagrid").options;
        if (!opts.rowDnd) { return; }
        row = row || t.datagrid("getRowData", index);
        tr = tr || t.datagrid("getRowDom", index);
        tr.each(function () {
            if ($.data(this, "draggable")) { return; }
            $(this).draggable({
                disabled: false, revert: true, edge: 5, delay: 300, cursor: "default", deltaX: 10, deltaY: 5,
                proxy: function (source) {
                    var tr = $("<tr><td><span class='tree-dnd-icon tree-dnd-no' >&nbsp;</span></td></tr>").addClass("datagrid-row datagrid-row-selected"),
                        cells = t.datagrid("getRowDom", index).clone().find("td").removeClass("datagrid-row-over").each(function (i) {
                            if (i < 8) { tr.append(this); }
                        });
                    if (cells.length > 8) {
                        $("<td style='width: 40px;'>...</td>").appendTo(tr);
                    }
                    return $("<table class='tree-node-proxy'></table>").append(tr).appendTo("body").hide();
                },
                onBeforeDrag: function (e) {
                    if (!opts.rowDnd || e.which != 1 || e.target.type == "checkbox" || getEditingRowIndexes(target).length) {
                        return false;
                    }
                    if ($.isFunction(opts.onRowBeforeDrag) && opts.onRowBeforeDrag.call(target, index, row) == false) {
                        return false;
                    }
                    setRowsDroppable();
                },
                onStartDrag: function (e) {
                    $(this).draggable("proxy").css({
                        left: -10000, top: -10000
                    });
                    if ($.isFunction(opts.onRowStartDrag)) {
                        opts.onRowStartDrag.call(target, index, row);
                    }
                },
                onStopDrag: function () {
                    if ($.isFunction(opts.onRowStopDrag)) {
                        opts.onRowStopDrag.call(target, index, row);
                    }
                },
                onDrag: function (e) {
                    var x1 = e.pageX, y1 = e.pageY,
                        x2 = e.data.startX, y2 = e.data.startY,
                        d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
                    if (d > 15) {
                        $(this).draggable("proxy").show();
                    }
                    this.pageY = e.pageY;
                }
            });
        });
        function setRowsDroppable() {
            t.datagrid("getPanel").find("div.datagrid-view div.datagrid-body table.datagrid-btable tr.datagrid-row[datagrid-row-index]").each(function () {
                if ($.data(this, "droppable")) { return; }
                $(this).droppable({
                    accept: "tr.datagrid-row[datagrid-row-index]",
                    onDragEnter: function (e, source) {
                        var dragger = $(source),
                            dropper = $(this),
                            dragIndex = window.parseInt(dragger.attr("datagrid-row-index"), 10),
                            dropIndex = window.parseInt(dropper.attr("datagrid-row-index"), 10),
                            rows = t.datagrid("getRows"),
                            dragRow = rows[dragIndex],
                            dropRow = rows[dropIndex],
                            dropTr = t.datagrid("getRowDom", dropIndex),
                            mark = dropTr.find("td"),
                            dnd = {
                                dragger: dragger,
                                dropper: dropper,
                                dragIndex: dragIndex,
                                dropIndex: dropIndex,
                                dragRow: dragRow,
                                dropRow: dropRow,
                                mark: mark
                            };
                        $.data(this, "datagrid-row-dnd", dnd);
                        if ($.isFunction(opts.onRowDragEnter) && opts.onRowDragEnter.call(target, dropRow, dragRow) == false) {
                            setDraggableStatus(dragger, false);
                            mark.removeClass("datagrid-row-dnd-top datagrid-row-dnd-bottom");
                            dropper.droppable("disable");
                        }
                    },
                    onDragOver: function (e, source) {
                        var dropper = $(this),
                            dopts = dropper.droppable("options");
                        if (dopts.disabled) { return; }
                        var dnd = $.data(this, "datagrid-row-dnd"),
                            dragger = dnd.dragger,
                            mark = dnd.mark,
                            pageY = source.pageY,
                            top = dropper.offset().top,
                            height = top + dropper.outerHeight(),
                            cls = pageY > top + (height - top) / 2
                                ? "datagrid-row-dnd-bottom"
                                : "datagrid-row-dnd-top";
                        setDraggableStatus(dragger, true);
                        mark.removeClass("datagrid-row-dnd-top datagrid-row-dnd-bottom").addClass(cls);

                        if ($.isFunction(opts.onRowDragOver) && opts.onRowDragOver.call(target, dnd.dropDow, dnd.dragRow) == false) {
                            setDraggableStatus(dragger, false);
                            mark.removeClass("datagrid-row-dnd-top datagrid-row-dnd-bottom");
                            dropper.droppable("disable");
                        }
                    },
                    onDragLeave: function (e, source) {
                        var dnd = $.data(this, "datagrid-row-dnd"),
                            dragger = dnd.dragger,
                            mark = dnd.mark;
                        setDraggableStatus(dragger, false);
                        mark.removeClass("datagrid-row-dnd-top datagrid-row-dnd-bottom");
                        if ($.isFunction(opts.onRowDragLeave)) {
                            opts.onRowDragLeave.call(target, dnd.dropDow, dnd.dragRow);
                        }
                    },
                    onDrop: function (e, source) {
                        var dnd = $.data(this, "datagrid-row-dnd"),
                            mark = dnd.mark,
                            point = mark.hasClass("datagrid-row-dnd-top") ? "top" : "bottom";
                        if ($.isFunction(opts.onRowBeforeDrop) && opts.onRowBeforeDrop.call(target, dnd.dropDow, dnd.dragRow, point) == false) {
                            mark.removeClass("datagrid-row-dnd-top datagrid-row-dnd-bottom");
                            return false;
                        }
                        t.datagrid("moveRow", {
                            target: dnd.dropIndex,
                            source: dnd.dragIndex,
                            point: point
                        });
                        mark.removeClass("datagrid-row-dnd-top datagrid-row-dnd-bottom");
                        if ($.isFunction(opts.onRowDrop)) {
                            opts.onRowDrop.call(target, dnd.dropDow, dnd.dragRow, point);
                        }
                    }
                });
            });
        }
    }

    function initRowMouseEvent(t, opts) {
        var target = t[0];
        t.datagrid("getPanel").panel("body").delegate("tr.datagrid-row", {
            "mouseenter.datagrid-extensions": function (e) {
                var tr = $(this);
                if (tr.is(".datagrid-row-editing")) {
                    return;
                }
                var index = getTrIndex(tr);
                if (index == -1) {
                    return;
                }
                var row = t.datagrid("getRowData", index);
                resetRowDnd(target, index, t, opts, row, tr);
            },
            "mouseleave.datagrid-extensions": function () {
                //var tr = $(this),
                //    index = getTrIndex(tr);
                //if (index == -1) {
                //    return;
                //}
            }
        });
    }

    function initHeaderFiltersData(t, opts) {
        var target = t[0],
            state = $.data(target, "datagrid");
        state.hiddenRows = [];
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initHeaderFiltersData(t, opts);
        initRowMouseEvent(t, opts);
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);



    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；隐藏当前 easyui-datagrid 当前页数据中指定行的数据；该方法的参数 param 可以是以下两种类型：
        //      待查找的行数据的 idField(主键) 字段值；
        //      function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 function 类型，则 findRow 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则表示找到需要查找的结果，立即停止循环调用并隐藏该行数据；
        //          如果回调函数始终未返回 true，则该回调函数会一直遍历 rows 直到最后。
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        hideRow: function (jq, param) { return jq.each(function () { hideRow(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；显示当前 easyui-datagrid 当前页数据中指定行的数据；该方法的参数 param 可以是以下两种类型：
        //      待查找的行数据的 idField(主键) 字段值；
        //      function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 function 类型，则 findRow 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则表示找到需要查找的结果，立即停止循环调用并显示该行数据；
        //          如果回调函数始终未返回 true，则该回调函数会一直遍历 rows 直到最后。
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        showRow: function (jq, param) { return jq.each(function () { showRow(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；隐藏当前 easyui-datagrid 当前页数据中指定多行的数据；该方法的参数 param 可以是以下三种类型：
        //      Function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 Function 类型，则 hideRows 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则该行数据将会被隐藏；
        //      Array 类型，数组中的每一项都可以定义为如下类型：
        //          待查找的行数据的 idField(主键) 字段值；
        //          Function 类型；具体回调函数签名参考 hideRow 方法中 param 参数为 function 类型时的定义；
        //          当 param 参数定义为 Array 类型时，则 hideRows 方法会对数组中的每一项循环调用 hideRow 方法；
        //      Boolean 类型且为 true：则 hideRows 将会隐藏 easyui-datagrid 当前页的所有数据。
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        hideRows: function (jq, param) { return jq.each(function () { hideRows(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；显示当前 easyui-datagrid 当前页数据中指定多行的数据；该方法的参数 param 可以是以下三种类型：
        //      Function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 Function 类型，则 showRows 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则该行数据将会被显示；
        //      Array 类型，数组中的每一项都可以定义为如下类型：
        //          待查找的行数据的 idField(主键) 字段值；
        //          Function 类型；具体回调函数签名参考 showRow 方法中 param 参数为 function 类型时的定义；
        //          当 param 参数定义为 Array 类型时，则 showRows 方法会对数组中的每一项循环调用 showRow 方法；
        //      Boolean 类型且为 true：则 showRows 将会显示 easyui-datagrid 当前页的所有数据。
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        showRows: function (jq, param) { return jq.each(function () { showRows(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；获取当前 easyui-datagrid 当前页所有隐藏的行数据所构成的一个 Array 对象。
        getHiddenRows: function (jq) { return getHiddenRows(jq[0]); },

        //  扩展 easyui-datagrid 的自定义方法；获取当前 easyui-datagrid 当前页所有显示的行数据所构成的一个 Array 对象。
        getVisibleRows: function (jq) { return getVisibleRows(jq[0]); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用表格的行节点拖动功能；
        //  Boolean 类型值，默认为 false。
        rowDnd: false,

        //  扩展 easyui-datagrid 的自定义事件；该事件表示拖动 data-row(数据行) 之前触发的动作；该事件回调函数提供如下两个参数：
        //      index: 表示要拖动的 data-row(数据行) 索引号(从 0 开始计数)；
        //      row:   表示被拖动的 data-row(数据行) 的行数据对象，是一个 JSON-Object；
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        //  备注：如果该事件函数返回 false，则取消当前的拖动 data-row(数据行) 操作。
        onRowBeforeDrag: function (index, row) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示开始拖动 data-row(数据行) 时触发的动作；该事件回调函数提供如下两个参数：
        //      index:  表示被拖动的 data-row(数据行) 的索引号，从 0 开始计数；
        //      row:    表示被拖动的 data-row(数据行) 的行数据对象，是一个 JSON-Object。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onRowStartDrag: function (index, row) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示结束拖动 data-row(数据行) 时触发的动作；该事件回调函数提供如下两个参数：
        //      index:  表示被拖动的 data-row(数据行) 的索引号，从 0 开始计数；
        //      row:    表示被拖动的 data-row(数据行) 的行数据对象，是一个 JSON-Object。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onRowStopDrag: function (index, row) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示当有其他的 data-row(数据行) 被拖动至当前 data-row(数据行) 时所触发的动作；该事件回调函数提供如下两个参数：
        //      targetRow: 表示当前 data-row(数据行) 的行数据对象，是一个 JSON-Object；
        //      sourceRow: 表示拖动过来的 data-row(数据行) 行数据对象，是一个 JSON-Object。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        //  备注：如果该事件函数返回 false，则立即取消当前的 data-row(数据行) 接收拖动过来对象的操作，并禁用当前 data-row(数据行) 的 droppable 效果；
        onRowDragEnter: function (targetRow, sourceRow) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示当有其他的 data-row(数据行) 被拖动至当前 data-row(数据行) 后并在上面移动时所触发的动作；该事件回调函数提供如下两个参数：
        //      targetRow: 表示当前 data-row(数据行) 的行数据对象，是一个 JSON-Object；
        //      sourceRow: 表示拖动过来的 data-row(数据行) 行数据对象，是一个 JSON-Object。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        //  备注：如果该事件函数返回 false，则立即取消当前的 data-row(数据行) 接收拖动过来对象的操作，并禁用当前 data-row(数据行) 的 droppable 效果；
        onRowDragOver: function (targetRow, sourceRow) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示当有其他的 data-row(数据行) 被拖动至当前 data-row(数据行) 后并拖动离开时所触发的动作；该事件回调函数提供如下两个参数：
        //      targetRow: 表示当前 data-row(数据行) 的行数据对象，是一个 JSON-Object；
        //      sourceRow: 表示拖动过来的 data-row(数据行) 行数据对象，是一个 JSON-Object。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onRowDragLeave: function (targetRow, sourceRow) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示放置 data-row(数据行) 之前触发的动作；该事件回调函数提供如下三个参数：
        //      targetRow: 表示目标位置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      sourceRow: 表示要放置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      point:  表示放置到目标节点 target 的位置，String 类型，可能的值包括：
        //          "top":      表示放置到目标位置 target 的上一格位置；
        //          "bottom":   表示追加为目标位置 target 的下一格位置；
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        //  如果该事件函数返回 false，则会立即停止放置数据行操作；
        onRowBeforeDrop: function (targetRow, sourceRow, point) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示放置 data-row(数据行) 之后触发的动作；该事件回调函数提供如下三个参数：
        //      targetRow: 表示目标位置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      sourceRow: 表示要放置的 data-row(数据行) 索引号(从 0 开始计数)；
        //      point:  表示放置到目标节点 target 的位置，String 类型，可能的值包括：
        //          "top":      表示放置到目标位置 target 的上一格位置；
        //          "bottom":   表示追加为目标位置 target 的下一格位置；
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onRowDrop: function (targetRow, sourceRow, point) { }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.getCellData.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-25
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.getRowData.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var getCellData = function (target, pos) {
        if (!pos || !pos.field || !$.isNumeric(pos.index) || pos.index < 0) { return; }
        var t = $(target), row = t.datagrid("getRowData", pos.index);
        return row ? row[pos.field] : row;
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前页指定单元格的数据；该函数定义如下参数：
        //  pos：表示单元格的位置，为一个 JSON-Object 对象，该 JSON 定义如下属性：
        //          field:  表示要获取的单元格位于哪个列；
        //          index:  表示要获取的单元格位于哪个行的行索引号，从 0 开始；
        //  返回值：如果当前页存在指定列的指定行，则返回该列中指定行及指定列的单元格数据；否则返回 undefined。
        getCellData: function (jq, pos) { return getCellData(jq[0], pos); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.operateColumn.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-18
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.getColumnInfo.js
*   3、jeasyui.extensions.datagrid.getDom.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");



    function unfreezeColumn(target, field) {
        var state = $.data(target, "datagrid");
        if (state.multiLineHeaders) {
            $.error("不支持在多行表头情况下执行取消冻结表格列的操作。");
        }
        var t = $(target), fields = t.datagrid("getColumnFields", false)
        if ($.array.contains(fields, field)) {
            return;
        }
        t.datagrid("moveColumn", {
            target: fields[0],
            source: field,
            point: "before"
        });
    }

    function freezeColumn(target, field) {
        var state = $.data(target, "datagrid");
        if (state.multiLineHeaders) {
            $.error("不支持在多行表头情况下执行冻结表格列的操作。");
        }
        var t = $(target), frozenFields = t.datagrid("getColumnFields", true),
            isFrozen = isFrozenColumn(target, field, frozenFields);
        if (isFrozen) { return; }
        t.datagrid("moveColumn", {
            target: frozenFields[frozenFields.length - 1],
            source: field,
            point: "after"
        });
    }




    //  param: { field: string, point: string("before"/default, "after") }
    function shiftColumn(target, param) {
        if (!param || !param.field || (param.point != "before" && param.point != "after")) { return; }
        var state = $.data(target, "datagrid");
        if (state.multiLineHeaders) {
            $.error("不支持在多行表头情况下执行移动表格列的操作。");
        }
        var sourceField = param.field,
            targetColumn = param.point == "before" ? getPrevVisibleColumn(target, sourceField) : getNextVisibleColumn(target, sourceField);
        if (!targetColumn || !targetColumn.field) { return; }
        var t = $(target), targetField = targetColumn.field;
        t.datagrid("moveColumn", {
            target: targetField,
            source: sourceField,
            point: param.point
        });
    }

    function getPrevVisibleColumn(target, field) {
        if (!field) { return undefined; }
        var t = $(target), cols = t.datagrid("getColumnOptions", "all");
        if (!cols || !cols.length) { return undefined; }
        var index = -1;
        return $.array.last(cols, function (val, i) {
            if (val.field == field) {
                index = i;
            }
            return index != -1 && i < index && !val.hidden ? true : false;
        });
    }

    function getNextVisibleColumn(target, field) {
        if (!field) { return undefined; }
        var t = $(target), cols = t.datagrid("getColumnOptions", "all");
        if (!cols || !cols.length) { return undefined; }
        var index = -1;
        return $.array.first(cols, function (val, i) {
            if (val.field == field) {
                index = i;
            }
            return index != -1 && i > index && !val.hidden ? true : false;
        });
    }




    //  param: { target: string/field, source: string/field, point: string("before"/default, "after") }
    function moveColumn(target, param) {
        if (!param || !param.target || !param.source || param.target == param.source || (param.point != "before" && param.point != "after")) {
            return;
        }
        var state = $.data(target, "datagrid"),
            opts = state.options;
        if (state.multiLineHeaders) {
            $.error("不支持在多行表头情况下执行移动表格列的操作。");
        }
        var t = $(target),
            targetField = param.target,
            sourceField = param.source,
            fields = t.datagrid("getColumnFields", "all"),
            targetIndex = $.array.indexOf(fields, targetField),
            sourceIndex = $.array.indexOf(fields, sourceField);
        if (targetIndex == -1 || sourceIndex == -1 || targetIndex == sourceIndex) {
            return;
        }
        var sourceColumnOpt = t.datagrid("getColumnOption", sourceField);
        if (sourceColumnOpt.movable != undefined && sourceColumnOpt.movable == false) { return; }
        var frozenFields = t.datagrid("getColumnFields", true),
            targetFrozen = isFrozenColumn(target, targetField, frozenFields),
            sourceFrozen = isFrozenColumn(target, sourceField, frozenFields),
            point = param.point;
        if (sourceIndex == (point == "before" ? targetIndex - 1 : targetIndex + 1) && (targetFrozen == sourceFrozen)) {
            return;
        }
        if ($.isFunction(opts.onBeforeMoveColumn) && opts.onBeforeMoveColumn.call(target, sourceField, targetField, point) == false) {
            return;
        }
        var p = t.datagrid("getPanel"),
            v = p.find("div.datagrid-view"),
            v1 = v.find("div.datagrid-view1"),
            v2 = v.find("div.datagrid-view2"),
            hr1 = v1.find("div.datagrid-header table.datagrid-htable tr.datagrid-header-row"),
            hr2 = v2.find("div.datagrid-header table.datagrid-htable tr.datagrid-header-row"),
            br1 = v1.find("div.datagrid-body table.datagrid-btable tr.datagrid-row"),
            br2 = v2.find("div.datagrid-body table.datagrid-btable tr.datagrid-row"),
            targetHeaderTd = (targetFrozen ? hr1 : hr2).find("td[field=" + targetField + "]"),
            sourceHeaderTd = (sourceFrozen ? hr1 : hr2).find("td[field=" + sourceField + "]"),
            targetRow = targetFrozen ? br1 : br2,
            sourceRow = sourceFrozen ? br1 : br2,
            targetCopts = t.datagrid("getColumnOption", targetField),
            sourceCopts = sourceColumnOpt,
            targetColumns = targetFrozen ? opts.frozenColumns[0] : opts.columns[0],
            sourceColumns = sourceFrozen ? opts.frozenColumns[0] : opts.columns[0];

        targetHeaderTd[point](sourceHeaderTd);
        targetRow.each(function (i) {
            var targetTd = $(this).find("td[field=" + targetField + "]"),
                sourceTd = $(sourceRow[i]).find("td[field=" + sourceField + "]");
            targetTd[point](sourceTd);
        });

        $.array.remove(sourceColumns, sourceCopts);
        var targetCoptsIndex = $.array.indexOf(targetColumns, targetCopts);
        $.array.insert(targetColumns, point == "before" ? targetCoptsIndex : targetCoptsIndex + 1, sourceCopts);

        t.datagrid("fixColumnSize");
        if (sourceFrozen) {
            if (!targetFrozen) {
                var index = $.array.indexOf(state.columnOptions, targetCopts, function (col) { return col.field == targetField; });
                $.array.insert(state.columnOptions, point == "before" ? index : index + 1, sourceCopts);
                $.array.insert(state.originalColumnOptions, point == "before" ? index : index + 1, $.extend({}, sourceCopts));
            }
        } else {
            var index = $.array.indexOf(state.columnOptions, sourceCopts, function (col) { return col.field == sourceField; });
            if (targetFrozen) {
                $.array.removeAt(state.columnOptions, index);
                $.array.removeAt(state.originalColumnOptions, index);
            } else {
                var copts = state.columnOptions[index],
                    bcopts = state.originalColumnOptions[index];
                $.array.removeAt(state.columnOptions, index);
                $.array.removeAt(state.originalColumnOptions, index);

                var tindex = $.array.indexOf(state.columnOptions, targetCopts, function (col) { return col.field == targetField; });
                $.array.insert(state.columnOptions, point == "before" ? tindex : tindex + 1, copts);
                $.array.insert(state.originalColumnOptions, point == "before" ? tindex : tindex + 1, bcopts);
            }
        }

        if ($.isFunction(opts.onMoveColumn)) {
            opts.onMoveColumn.call(target, sourceField, targetField, point);
        }
    }

    function popColumn(target, field) {
        var state = $.data(target, "datagrid");
        if (state.multiLineHeaders) {
            $.error("不支持在多行表头情况下执行删除表格列的操作。");
        }
        var t = $(target),
            copts = t.datagrid("getColumnOption", field);
        if (copts) {
            t.datagrid("deleteColumn", field);
            return copts;
        } else {
            return undefined;
        }
    }



    function deleteColumn(target, field) {
        var state = $.data(target, "datagrid");
        if (state.multiLineHeaders) {
            $.error("不支持在多行表头情况下执行删除表格列的操作。");
        }
        var opts = state.options;
        if ($.isFunction(opts.onBeforeDeleteColumn) && opts.onBeforeDeleteColumn.call(target, field) == false) {
            return;
        }
        var frozen = isFrozenColumn(target, field), removed = removeField(target, field, frozen);
        if (removed) {
            var t = $(target);
            t.datagrid("getColumnDom", { field: field, header: true }).remove();
            if (frozen) {
                t.datagrid("fixColumnSize");
            }
            if ($.isFunction(opts.onDeleteColumn)) {
                opts.onDeleteColumn.call(target, field);
            }
        }
    }

    function removeField(target, field, frozen) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options,
            frozen = frozen == undefined ? isFrozenColumn(target, field) : frozen;
        return remove(frozen ? opts.frozenColumns : opts.columns);
        function remove(columns) {
            if (!columns || !columns.length) {
                return false;
            }
            var ret = false;
            $.each(columns, function (index, cols) {
                var i = $.array.indexOf(cols, field, function (col) {
                    return col.field == field;
                });
                if (i > -1) {
                    $.array.removeAt(cols, i);
                    ret = true;
                    $.array.remove(state.columnOptions, field, function (col) {
                        return col.field == field;
                    });
                    $.array.remove(state.originalColumnOptions, field, function (col) {
                        return col.field == field;
                    });
                }
            });
            return ret;
        }
    }

    function isFrozenColumn(target, field, frozenFields) {
        if (!field) {
            return undefined;
        }
        var fields = frozenFields && frozenFields.length ? frozenFields : $(target).datagrid("getColumnFields", true);
        return $.array.contains(fields, field);
    }



    function isMultiLineHeaders(target) {
        var state = $.data(target, "datagrid"),
            opts = state.options;
        if (opts.columns && opts.columns.length > 1 && opts.columns[0].length && opts.columns[1].length) {
            return true;
        }
        if (opts.frozenColumns && opts.frozenColumns.length > 1 && opts.frozenColumns[0].length && opts.frozenColumns[1].length) {
            return true;
        }
        return false;
    }

    function initExtendColumnOptions(t, opts) {
        var target = t[0],
            state = $.data(target, "datagrid"),
            cols = t.datagrid("getColumnOptions", "all");
        $.each(cols, function (i, col) {
            $.union(col, $.fn.datagrid.extensions.columnOptions);
        });
        var columnOptions = t.datagrid("getColumnOptions", false);
        state.columnOptions = $.array.filter(columnOptions, function (col) {
            return col.title ? true : false;
        });
        state.originalColumnOptions = $.array.map(state.columnOptions, function (col) {
            return $.extend({}, col);
        });
        state.multiLineHeaders = isMultiLineHeaders(target);
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initExtendColumnOptions(t, opts);
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);



    //  增加了 easyui-datagrid 中列 columnOption 的部分自定义扩展属性
    var columnOptions = {

        // 表示该列是否可移动，其值可以是 Boolean 类型；
        // 默认为 true。
        // 该属性用户在“移动列”时判定
        movable: true
    };
    
    if ($.fn.datagrid.extensions.columnOptions) {
        $.extend($.fn.datagrid.extensions.columnOptions, columnOptions);
    }
    else {
        $.fn.datagrid.extensions.columnOptions = columnOptions;
    }

    

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；删除指定的列；该方法的参数 field 表示要删除的列的 field 值；
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        deleteColumn: function (jq, field) { return jq.each(function () { deleteColumn(this, field); }); },

        //  扩展 easyui-datagrid 的自定义方法；删除指定的列并返回该列的 ColumnOption 值；该方法的参数 field 表示要删除的列的 field 值；
        //  返回值：返回参数 field 值所表示的列的 ColumnOption 值。如果当前 easyui-datagrid 不存在该列，则返回 undefined。
        popColumn: function (jq, field) { return popColumn(jq[0], field); },

        //  扩展 easyui-datagrid 的自定义方法；移动指定的列到另一位置；该方法的参数 param 为一个 JSON-Object，定义包含如下属性：
        //      target: 表示目标位置列的 field 值；
        //      source: 表示要移动的列的 field 值；
        //      point:  表示移动到目标列的位置，String 类型，可选的值包括：
        //          before: 表示将 source 列移动至 target 列的左侧；
        //          after:  表示将 source 列移动值 target 列的右侧；
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        //  注意：此方法在多行表头情况下无效。
        moveColumn: function (jq, param) { return jq.each(function () { moveColumn(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；移动指定的列挪动一格位置；该方法的参数 param 为一个 JSON-Object，定义包含如下属性：
        //      field:  表示要挪动的列的 field 值；
        //      porint: 表示挪动 field 列的方式，String 类型，可选的值包括：
        //          before: 表示将该列向左挪动一格；
        //          after:  表示将该列向右挪动一格；
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        //  注意：此方法在多行表头情况下无效。
        shiftColumn: function (jq, param) { return jq.each(function () { shiftColumn(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；冻结指定的列；该方法的参数 field 表示要冻结的列的 field 值。
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        //  注意：此方法在多行表头情况下无效。
        //      当前表格在执行此方法前必须存在至少一个冻结列，否则此方法无效；
        freezeColumn: function (jq, field) { return jq.each(function () { freezeColumn(this, field); }); },

        //  扩展 easyui-datagrid 的自定义方法；取消冻结指定的列；该方法的参数 field 表示要取消冻结的列的 field 值。
        //  返回值：返回表示当前 easyui-datagrid 的 jQuery 链式对象。
        //  注意：此方法在多行表头情况下无效。
        //      当前表格在执行此方法前必须存在至少一个非冻结列，否则此方法无效；
        unfreezeColumn: function (jq, field) { return jq.each(function () { unfreezeColumn(this, field); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义事件；该事件表示删除指定的列前触发的动作；该事件回调函数提供如下参数：
        //      field:  表示要被删除的列的 field 值。
        //  备注：如果该事件回调函数返回 false，则不进行删除列的操作。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onBeforeDeleteColumn: function (field) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示删除指定的列后触发的动作；该事件回调函数提供如下参数：
        //      field:  表示要被删除的列的 field 值。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onDeleteColumn: function (field) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示移动指定的列前触发的动作；该事件回调函数提供如下参数：
        //      source:  表示要被移动的列的 field 值。
        //      target:  表示目标位置的列的 field 值。
        //      point :  表示移动的方式；这是一个 String 类型值，可能的值包括：
        //          "before":   表示将列 source 移动至列 target 的前一格位置；
        //          "after" :   表示将列 source 移动至列 target 的后一格位置；
        //  备注：如果该事件回调函数返回 false，则不进行移动列的操作。
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onBeforeMoveColumn: function (source, target, point) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示移动指定的列后触发的动作；该事件回调函数提供如下参数：
        //      source:  表示要被移动的列的 field 值。
        //      target:  表示目标位置的列的 field 值。
        //      point :  表示移动的方式；这是一个 String 类型值，可能的值包括：
        //          "before":   表示将列 source 移动至列 target 的前一格位置；
        //          "after" :   表示将列 source 移动至列 target 的后一格位置；
        //  该事件函数中的 this 指向当前 easyui-datagrid 的 DOM 对象(非 jQuery 对象)；
        onMoveColumn: function (source, target, point) { }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.navigating.js
* 开发 糖古屋
* 由 落阳 整理
* 最近更新：2016-05-10
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 Lixilin personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    function onNavigatePaginate(paginateType, data) {
        if (paginateType == "prev") {
            $(this).datagrid("selectRow", $(this).datagrid("getRows").length - 1);
        } else {
            $(this).datagrid("selectRow", 0);
        }
    }

    function prevPage(t, opts, callback) {
        if (opts.pagination) {
            var pager = t.datagrid("getPager"), currentPageNumber = pager.pagination("options").pageNumber;
            if (currentPageNumber > 1) {
                //缓存回调给datagrid对象
                opts.successCallBackForNavigating = function (data) {
                    if ($.isFunction(opts.onNavigatePaginate)) { opts.onNavigatePaginate.call(this, "prev", data); }
                    if (callback && $.isFunction(callback)) {
                        callback.call(t[0], data);
                    }
                };
                pager.pagination("select", currentPageNumber - 1);
            }
        }
    }

    function nextPage(t, opts, callback) {
        if (opts.pagination) {
            var pager = t.datagrid("getPager"), pagerOpts = pager.pagination("options"),
                currentPageNumber = pagerOpts.pageNumber, recordsTotal = pagerOpts.total, pageSize = pagerOpts.pageSize;
            var totalPage = Math.ceil(recordsTotal / pageSize) || 1;
            if (currentPageNumber < totalPage) {
                //缓存回调给datagrid对象
                opts.successCallBackForNavigating = function (data) {
                    if ($.isFunction(opts.onNavigatePaginate)) { opts.onNavigatePaginate.call(this, "next", data); }
                    if (callback && $.isFunction(callback)) {
                        callback.call(t[0]);
                    }
                };
                pager.pagination("select", currentPageNumber + 1);
            }
        }
    }

    function initKeyNavigatingEvent(t, opts) {
        if (!opts.navigatingWithKey) { return; }
        if (opts.pagination) {
            var po = t.datagrid("getPager"), popts = po.pagination("options");
            var _onSelectPage = popts.onSelectPage;
            popts.onSelectPage = function (pn, ps) {
                /*重写 datagrid 的 onSelectPage */
                opts.pageNumber = pn || 1;
                opts.pageSize = ps;
                po.pagination("refresh", { pageNumber: pn, pageSize: ps });

                var queryParams = $.extend({ page: opts.pageNumber, rows: opts.pageSize }, opts.queryParams);
                if (opts.sortName) {
                    $.extend(queryParams, { sort: opts.sortName, order: opts.sortOrder });
                }
                if (opts.onBeforeLoad.call(t[0], queryParams) == false) {
                    return;
                }
                t.datagrid("loading");
                var loadResult = opts.loader.call(t[0], queryParams, function (data) {
                    t.datagrid("loaded");
                    t.datagrid("loadData", data);
                    //执行回调
                    if ($.isFunction(opts.successCallBackForNavigating)) {
                        opts.successCallBackForNavigating.call(t[0], data);
                        opts.successCallBackForNavigating = undefined;
                    }
                }, function () {
                    t.datagrid("loaded");
                    opts.onLoadError.apply(t[0], arguments);
                });
                if (loadResult == false) {
                    t.datagrid("loaded");
                }
            };
        }
        t.datagrid("getPanel").panel("panel").attr('tabindex', 1).off('keydown.navigating').on('keydown.navigating', function (e) {
            switch (e.keyCode) {
                // Up
                case 38:
                    e.preventDefault();
                    var selected = t.datagrid("getSelections");
                    var targetIndex = -1;
                    if (selected && selected.length) {
                        var indexs = $.array.map(selected, function (item) {
                            return t.datagrid("getRowIndex", item);
                        });
                        var index = $.array.min(indexs);
                        if (index > 0) {
                            targetIndex = index - 1;
                            t.datagrid("selectRow", targetIndex);
                            if (opts.navigateHandler && opts.navigateHandler.up && $.isFunction(opts.navigateHandler.up)) {
                                opts.navigateHandler.up.call(t[0], targetIndex);
                            }
                        }
                        else {
                            prevPage(t, opts, function (data) {
                                if ($.util.isObject(data)) {
                                    targetIndex = data.rows.length - 1;
                                } else {
                                    targetIndex = data.length - 1;
                                }
                                if (opts.navigateHandler && opts.navigateHandler.up && $.isFunction(opts.navigateHandler.up)) {
                                    opts.navigateHandler.up.call(t[0], targetIndex);
                                }
                            });
                        }
                    } else {
                        targetIndex = t.datagrid("getRows").length - 1;
                        t.datagrid("selectRow", targetIndex);
                        if (opts.navigateHandler && opts.navigateHandler.up && $.isFunction(opts.navigateHandler.up)) {
                            opts.navigateHandler.up.call(t[0], targetIndex);
                        }
                    }
                    break;
                // Down
                case 40:
                    e.preventDefault();
                    var selected = t.datagrid("getSelections");
                    var targetIndex = -1;
                    if (selected && selected.length) {
                        var indexs = $.array.map(selected, function (item) {
                            return t.datagrid("getRowIndex", item);
                        });
                        var index = $.array.max(indexs), rows = t.datagrid("getRows");
                        if (index < rows.length - 1) {
                            targetIndex = index + 1;
                            t.datagrid("selectRow", targetIndex);
                            if (opts.navigateHandler && opts.navigateHandler.down && $.isFunction(opts.navigateHandler.down)) {
                                opts.navigateHandler.down.call(t[0], targetIndex);
                            }
                        }
                        else {
                            targetIndex = 0;
                            nextPage(t, opts, function () {
                                if (opts.navigateHandler && opts.navigateHandler.down && $.isFunction(opts.navigateHandler.down)) {
                                    opts.navigateHandler.down.call(t[0], targetIndex);
                                }
                            });
                        }
                    } else {
                        targetIndex = 0;
                        t.datagrid("selectRow", targetIndex);
                        if (opts.navigateHandler && opts.navigateHandler.down && $.isFunction(opts.navigateHandler.down)) {
                            opts.navigateHandler.down.call(t[0], targetIndex);
                        }
                    }
                    break;
                // Left
                case 37:
                    e.preventDefault(); prevPage(t, opts);
                    break;
                // Right
                case 39:
                    e.preventDefault(); nextPage(t, opts);
                    break;
                // Enter
                case 13:
                    if (opts.navigateHandler && opts.navigateHandler.enter && $.isFunction(opts.navigateHandler.enter)) {
                        e.preventDefault();
                        var selected = t.datagrid("getSelections");
                        if (selected) {
                            opts.navigateHandler.enter.call(t[0], selected);
                        }
                    }
                    break;
            }
        });
    };

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initKeyNavigatingEvent(t, opts);
        if (opts.navigatingWithKey) { t.datagrid("getPanel").panel("panel").focus(); }
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this, [
                            {
                                navigatingWithKey: "boolean"
                            }
                        ]), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);

    var methods = $.fn.datagrid.extensions.methods = {

    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义属性；表示是否开启按键导航功能；
        //      Up 键：selected 数据行上移
        //      Down 键：selected 数据行下移
        //      Left 键：上一页，仅在有上一页时有效
        //      Right 键：下一页，仅在有下一页时有效
        //      Enter 键：触发 datagrid onDblClickRow 事件，仅在有 selected 数据行时有效
        navigatingWithKey: true,

        //  扩展 easyui-datagrid 的自定义事件；表示通过按键导航进行翻页后触发的事件；该事件回调函数提供如下参数：
        //      paginateType:  表示翻页类型，其值可以是 prev、next，分别表示上一页、下一页；
        //      data: 表示翻页后的数据对象，该数据对象可能是 object（含 total、rows 属性），也可能是 array；
        //  该事件函数中的 this 指向当前 easyui-datarid 的 DOM 对象(非 jQuery 对象)；
        onNavigatePaginate: onNavigatePaginate,

        //  扩展 easyui-datagrid 的自定义对象；表示按键导航执行后触发的事件集合；该对象支持如下事件属性：
        //      up:  表示“上”按键导航后触发的事件，该事件的函数签名 targetIndex 表示导航后的数据行的索引；
        //      down:  表示“下”按键导航后触发的事件，该事件的函数签名 targetIndex 表示导航后的数据行的索引；
        //      enter:  表示“回车”按键导航后触发的事件，该事件的函数签名 selectedData 表示已经 selected 的数据行；
        //              注意：selectedData 的类型为 object 还是 array 取决于当前 easyui-datagrid 是单选还是多选；
        //  以上事件函数中的 this 指向当前 easyui-datarid 的 DOM 对象(非 jQuery 对象)；
        navigateHandler: {
            up: function (targetIndex) { },
            down: function (targetIndex) { },
            enter: function (selectedData) { }
        }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.liveSearch.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-24
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.css
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var liveSearch = function (target, param) {
        var t = $(target), panel = t.datagrid("getPanel"), cells, field, value = param, regular = false, ignoreCase = true, regexp;
        if ($.isPlainObject(param)) {
            value = param.value;
            field = param.field;
            regular = param.regular;
            ignoreCase = param.ignoreCase;
            cells = panel.find("div.datagrid-body tr.datagrid-row td[" + (field ? "field=" + field : "field") + "] div.datagrid-cell");
        } else {
            cells = panel.find("div.datagrid-body tr.datagrid-row td[field] div.datagrid-cell");
        }
        
        regexp = regular ? new RegExp(value, ignoreCase ? "gm" : "igm") : value;
        cells.each(function () {
            var cell = $(this);
            cell.find("span.datagrid-cell-hightlight").replaceWith(function () { return $(this).text(); });

            if (!value) { return; }
            var text = cell.html(); if (!text) { return; }
            cell.html($.string.replaceAll(text, value, "<span class='datagrid-cell-hightlight'>" + value + "</span>"));
        });
    };

    var clearLiveHighLight = function (target, field) {
        var t = $(target), panel = t.datagrid("getPanel"), cells;
        if (field == null || field == undefined) {
            cells = panel.find("div.datagrid-body tr.datagrid-row td[field] div.datagrid-cell");
        }
        else {
            cells = panel.find("div.datagrid-body tr.datagrid-row td[field=" + String(field) + "] div.datagrid-cell");
        }

        cells.each(function () {
            var cell = $(this);
            cell.find("span.datagrid-cell-hightlight").replaceWith(function () { return $(this).text(); });
        });
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；对当前 easyui-datagrid 中进行高亮关键词查询；该方法的 param 可以定义为如下两种类型：
        //      1、String 类型值：表示要对所有列进行的高亮查询关键词；
        //      2、JSON-Object：表示对特定列进行高亮查询的参数，该对象类型参数包含如下属性：
        //          field:      表示要进行高亮查询的列；
        //          value:      表示要进行高亮查询的关键词；
        //          regular:    Boolean 类型值，默认为 false；指示该关键词是否为正则表达式；
        //          ignoreCase: Boolean 类型值，默认为 true；指示高亮查询时是否忽略大小写。
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        liveSearch: function (jq, param) { return jq.each(function () { liveSearch(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；清除当前 easyui-datagrid 中进行高亮关键词查询后产生的高亮效果；该方法的 field 可以定义为如下类型：
        //      1、String 类型值：表示要对特定列的高亮效果进行清除，不提供该参数则表示要清除所有列的高亮效果；
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        clearLiveHighLight: function (jq, field) { return jq.each(function () { clearLiveHighLight(this, field); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.highlightColumn.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-12-02
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.getDom.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var highlightColumn000000 = function (target, field) {
        if (!field) { return; }
        var t = $(target);
        var state = $.data(t[0], "datagrid"), opts = state.options;
        if (state.highlightField) {
            t.datagrid("getColumnDom", { field: state.highlightField, header: true }).removeClass("datagrid-row-over");
        }
        t.datagrid("getColumnDom", { field: field, header: true }).filter(function () {
            return !$(this).parent().hasClass("datagrid-row-selected");
        }).addClass("datagrid-row-over");
        state.highlightField = field;
    };

    function highlightColumn(target, field) {
        var t = $(target),
            state = $.data(target, "datagrid");
        if (state.highlightField) {
            t.datagrid("getColumnDom", { field: state.highlightField, header: true }).removeClass("datagrid-row-over");
        }
        t.datagrid("getColumnDom", { field: field, header: true }).removeClass("datagrid-row-over").filter(function () {
            return !$(this).closest("tr.datagrid-row").is(".datagrid-row-selected");
        }).addClass("datagrid-row-over");
        state.highlightField = field;
    }

    function unhighlightColumn(target, field) {
        var t = $(target),
            state = $.data(target, "datagrid");
        if (state.highlightField) {
            t.datagrid("getColumnDom", { field: state.highlightField, header: true }).removeClass("datagrid-row-over");
        }
        t.datagrid("getColumnDom", { field: field, header: true }).removeClass("datagrid-row-over");
        state.highlightField = undefined;
    }





    // 初始化单元格鼠标事件
    function initRowCellMouseEvent(t, opts) {
        t.datagrid("getPanel").panel("body").delegate("tr.datagrid-header-row>td[field],tr.datagrid-row>td[field]", {
            "mouseenter.datagrid-extensions": function () {
                if (!opts.autoHighlightColumn) {
                    return;
                }
                var target = t[0],
                    td = $(this),
                    field = td.attr("field");
                highlightColumn(target, field);
            },
            "mouseleave.datagrid-extensions": function () {
                if (!opts.autoHighlightColumn) {
                    return;
                }
                var target = t[0],
                    td = $(this),
                    field = td.attr("field");
                unhighlightColumn(target, field);
            }
        });
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initRowCellMouseEvent(t, opts);
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.tabs.parseOptions(this),
                        $.parser.parseOptions(this, [
                            {
                                autoHighlightColumn: "boolean"
                            }
                        ]), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);


    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；使当前 easyui-datagrid 中指定的列 DOM 对象高亮显示；该函数定义如下参数：
        //      field: 要高亮显示的列的 field 名；
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        highlightColumn: function (jq, field) { return jq.each(function () { highlightColumn(this, field); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义属性，该属性表示是否启用列自动高亮显示功能；
        //  Boolean 类型值，默认为 false。 
        autoHighlightColumn: false
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.rowState.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-24
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var isChecked = function (target, index) {
        if (index == null || index == undefined) {
            return false;
        }
        var t = $(target), rows = t.datagrid("getChecked"),
            list = $.array.map(rows, function (val) { return t.datagrid("getRowIndex", val); });
        return $.array.contains(list, index);
    };

    var isSelected = function (target, index) {
        if (index == null || index == undefined) {
            return false;
        }
        var t = $(target), rows = t.datagrid("getSelections"),
            list = $.array.map(rows, function (val) { return t.datagrid("getRowIndex", val); });
        return $.array.contains(list, index);
    };

    var isEditing = function (target, index) {
        if (index == null || index == undefined) {
            return false;
        }
        var t = $(target), panel = t.datagrid("getPanel");
        return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "]").hasClass("datagrid-row-editing");
    };

    var getEditingRowIndex = function (target) {
        var array = getEditingRowIndexs(target);
        return array.length ? array[0] : -1;
    };

    var getEditingRowIndexs = function (target) {
        var t = $(target), panel = t.datagrid("getPanel"),
            rows = panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row.datagrid-row-editing").map(function () {
                return window.parseInt($(this).attr("datagrid-row-index"));
            }),
            array = $.array.distinct($.array.clone(rows));
        return array;
    };



    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；判断指定的 data-row(数据行) 是否被 check；该方法的参数 index 表示要判断的行的索引号，从 0 开始计数；
        //  返回值：如果参数 index 所表示的 data-row(数据行) 被 check，则返回 true，否则返回 false。
        isChecked: function (jq, index) { return isChecked(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；判断指定的 data-row(数据行) 是否被 select；该方法的参数 index 表示要判断的行的索引号，从 0 开始计数；
        //  返回值：如果参数 index 所表示的 data-row(数据行) 被 select，则返回 true，否则返回 false。
        isSelected: function (jq, index) { return isSelected(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；判断指定的 data-row(数据行) 是否开启行编辑状态；该方法的参数 index 表示要判断的行的索引号，从 0 开始计数；
        //  返回值：如果参数 index 所表示的 data-row(数据行) 正开启行编辑状态，则返回 true，否则返回 false。
        isEditing: function (jq, index) { return isEditing(jq[0], index); },

        //  扩展 easyui-datagrid 的自定义方法；获取当前表格中第一个开启了编辑状态的数据行的索引号(从 0 开始计数)；
        //  返回值：如果当前表格中存在开启了行编辑状态的行，则返回第一个编辑行的行索引号(从 0 开始计数)；否则返回 -1。
        getEditingRowIndex: function (jq) { return getEditingRowIndex(jq[0]); },

        //  扩展 easyui-datagrid 的自定义方法；获取当前表格中所有开启了行编辑状态的行的索引号(从 0 开始计数)；
        //  返回值：返回一个数组，数组中包含当前表格中所有已经开启了行编辑状态的行的索引号(从 0 开始计数)。
        getEditingRowIndexs: function (jq) { return getEditingRowIndexs(jq[0]); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.getColumnData.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-25
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    var getColumnData = function (target, field) {
        var t = $(target), rows = t.datagrid("getRows");
        return $.array.map(rows, function (val) { return val[field]; });
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中当前也指定列所有行的单元格数据所构成的一个数组；该函数定义如下参数：
        //      field: 要获取的数据的列的 field 名；
        //  返回值：返回一个数组，数组中每一个元素都是其数据行的该列的值，数组的长度等于 grid.datagrid("getRows") 的长度；
        //          如果传入的列名不存在，则返回数组的长度同样等于 grid.datagrid("getRows") 的长度，只是每个元素的值都为 undefined.
        getColumnData: function (jq, field) { return getColumnData(jq[0], field); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.export.js
* 开发 落阳
* 最近更新：2016-06-12
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 Lixilin personal All rights reserved.
*/
(function ($) {

    var defaults = {
        //解析并导出到excel的地址，用来解析传递过去的列集合、当前页数据集合，并最终导出到excel文件
        exportParserHref: "/Public/ExportToExcelFromDatagrid",
        mergeExtensionProperty: "mergeInfos"
    };

    function delHtmlTag(str) {
        return str.replace(/<[^>]+>/g, "");//去掉所有的html标记
    }

    var getMergeDoms = function (target) {
        var t = $(target), panel = t.datagrid("getPanel");
        return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row td.datagrid-td-merged");
    };

    var exportData = function (target, param) {
        var fileType = ["excel"].contains(param.fileType) ? param.fileType : "excel";
        var fileName = param.fileName, isAll = $.string.toBoolean(param.isAll);
        if (fileType == "excel") { return exportDataToExcel(target, fileName, isAll); }
    };

    var exportDataToExcel = function (target, fileName, isAll) {
        var t = $(target), dgOptions = t.datagrid("options"), rows = isAll ? [] : t.datagrid("getRows");
        if (!isAll && rows.length == 0) { return; }
        if (isAll && $.string.isNullOrWhiteSpace(dgOptions.url)) { return; }

        var lastFrozenColumns = getColumns(target, true), lastColumns = getColumns(target, false);
        //冻结列的列数组length，不一定等于常规列的列数组length
        //比如冻结列的合并单元格是2行2列的，而常规列的合并单元格是3行5列的
        //从同一个容器角度来说，冻结列的列数组length小于常规列的列数组length时，应该给冻结列加上rowspan
        //但冻结列的容器和常规列的容器是独立的，所以此时给冻结列加rowspan反而引发js错误
        //那么就需要特别处理这种情况
        //差值，大于0则表示冻结列行数多，小于0则表示常规列行数多，等于0则表示无需处理
        //行数少的，需要补全到同样的行数，并且需要修正其rowspan值
        var diffLength = lastFrozenColumns.length == 0 ? 0 : (lastFrozenColumns.length - lastColumns.length);
        if (diffLength < 0) {
            //常规列行数多
            var abs = Math.abs(diffLength);
            var cloneFrozenColumnsOnTopPosition = $.array.map(lastFrozenColumns[0], function (item) { return $.extend({}, item); });
            for (var i = 0; i < abs ; i++) {
                $.array.insert(lastFrozenColumns, 0, cloneFrozenColumnsOnTopPosition);
            }
            for (var i = 0; i < (abs + 1) ; i++) {
                $.each(lastFrozenColumns[i], function (index, item) {
                    item.rowspan = item.rowspan + abs;
                });
            }
        } else if (diffLength > 0) {
            //冻结列行数多
            var abs = Math.abs(diffLength);
            var cloneColumnsOnTopPosition = $.array.map(lastColumns[0], function (item) { return $.extend({}, item); });
            for (var i = 0; i < abs ; i++) {
                $.array.insert(lastColumns, 0, cloneColumnsOnTopPosition);
            }
            for (var i = 0; i < (abs + 1) ; i++) {
                $.each(lastColumns[i], function (index, item) {
                    item.rowspan = item.rowspan + abs;
                });
            }
        }
        //console.log(lastFrozenColumns);
        //console.log(lastColumns);
        //return;
        var maxGroup = lastFrozenColumns.length >= lastColumns.length ? lastFrozenColumns.length : lastColumns.length;
        var totalColumns = new Array(maxGroup);
        for (var k = 0; k < maxGroup; k++) {
            if (totalColumns[k] == undefined) { totalColumns[k] = []; }
            if (lastFrozenColumns.length > k) {
                $.util.merge(totalColumns[k], lastFrozenColumns[k]);
            }
            if (lastColumns.length > k) {
                $.util.merge(totalColumns[k], lastColumns[k]);
            }
        }
        //用formatter处理rows 为不影响datagrid本身的rows集合，先克隆rows
        var existFields = [], cloneRowsObj = $.extend(true, {}, rows), lastRows = [];
        for (var c in cloneRowsObj) {
            if ($.string.isNumeric(String(c))) { lastRows.push(cloneRowsObj[c]); }
        }

        for (var index = 0; index < totalColumns.length; index++) {
            totalColumns[index].forEach(function (itemCol, itemColIndex) {
                if (itemCol.formatter && $.isFunction(itemCol.formatter)) {
                    lastRows.forEach(function (itemRow, itemRowIndex) {
                        var spe = true, rowIndex = !dgOptions.idField ? itemRowIndex : t.datagrid("getRowIndex", itemRow[dgOptions.idField]);
                        for (var prop in itemRow) {
                            if (prop == itemCol.field) {
                                itemRow[prop] = delHtmlTag(itemCol.formatter.call(itemCol, itemRow[prop], itemRow, rowIndex));
                                if (!existFields.contains(itemCol.field)) { existFields.push(itemCol.field); }
                                spe = false;
                                break;
                            }
                        }
                        if (spe) {
                            //处理特殊情况，遍历了row的属性，却没找到itemCol.field
                            // field 随便写，通过formatter强行显示指定数据
                            //将field的属性写入row中，其值为formatter的返回值
                            if (itemCol.field && !$.string.isNullOrWhiteSpace(itemCol.field)) {
                                //若该field已存在于 其他列的field 中，则不处理formatter，事实上，easyui也不会对这种formatter进行处理
                                if (!existFields.contains(itemCol.field)) {
                                    itemRow[itemCol.field] = delHtmlTag(itemCol.formatter.call(itemCol, itemRow[itemCol.field], itemRow, rowIndex));
                                }
                            }
                        }
                    });
                }
            });
        }

        //从lastRows的每个row中移除属性值类型为 array 或 object 的属性
        for (var k = 0; k < lastRows.length; k++) {
            var row = lastRows[k];
            for (var pro in row) {
                var tempValue = row[pro];
                if ($.isArray(tempValue) || $.util.isObject(tempValue)) { delete row[pro]; }
            }
        }

        if (!isAll) {
            //检测rows的html中是否包含合并标记
            var mergeDoms = getMergeDoms(target);
            if (mergeDoms.length > 0) {
                var mergeExtensionProperty = defaults.mergeExtensionProperty + "_" + $.util.guid("N")
                mergeRules = [];

                //把合并信息扩展进rows中
                $.each(mergeDoms, function (index, item) {
                    var td = $(item), tr = td.parent(), field = td.attr("field"), rowIndex = tr.attr("datagrid-row-index"),
                        rowspan = td.attr("rowspan"), colspan = td.attr("colspan");
                    if ($.string.isNullOrWhiteSpace(rowspan)) { rowspan = "1"; }
                    if ($.string.isNullOrWhiteSpace(colspan)) { colspan = "1"; }
                    var mergeRule = { index: rowIndex, field: field, rowspan: rowspan, colspan: colspan };

                    var mergeRow = lastRows[rowIndex];
                    if (!mergeRow[mergeExtensionProperty]) {
                        mergeRow[mergeExtensionProperty] = [mergeRule];
                    } else {
                        mergeRow[mergeExtensionProperty].push(mergeRule);
                    }
                });

                //序列化rows中的合并信息
                $.each(lastRows, function (index, row) {
                    if (row[mergeExtensionProperty]) {
                        row[mergeExtensionProperty] = JSON.stringify(row[mergeExtensionProperty]);
                    }
                });
            }
        }
        

        //组装参数
        var param = {
            data: JSON.stringify(lastRows),
            columns: JSON.stringify(totalColumns),
            fileName: fileName == undefined ? "" : fileName,
            url: isAll ? dgOptions.url : ""
        };


        //console.log("********************");
        //console.log("最终列集合：");
        //console.log(totalColumns);
        //console.log("********************");
        //console.log("最终本页数据集合：");
        //console.log(lastRows);
        //console.log("********************");
        //console.log("参数：");
        //console.log(param);
        //console.log("********************");
        //return;
        //模拟form提交完成导出excel操作
        $("iframe[name='hiddenIframe']").remove();
        $("form[target='hiddenIframe']").remove();

        //form的action指向，需结合后台配合，因此本扩展不是真正的easyui扩展。
        var tempForm = $('<form action="' + defaults.exportParserHref + '" target="hiddenIframe" method="post"></form>');
        for (var prop in param) {
            tempForm.append("<input name=\"" + prop + "\" type=\"hidden\" value='" + param[prop] + "' / >");
        }

        $("body").append("<iframe src=\"about:blank\" name=\"hiddenIframe\" style=\"display:none;\"></iframe>").append(tempForm);
        tempForm.submit();
    };

    var getColumns = function (target, frozen) {
        var t = $(target), dgOptions = t.datagrid("options");

        //取目标列集合
        var fColumns = frozen == true ? (dgOptions.frozenColumns || [[]]) : (dgOptions.columns || [[]]).clone();

        //过滤checkbox列和hidden列
        var ddddd = fColumns.clone();
        for (var k = 0; k < fColumns.length; k++) {
            var tempLen = fColumns[k].length;
            for (var inK = 0; inK < tempLen; inK++) {
                var needRemove = false, itemFc = fColumns[k][inK];
                //checkbox列
                if (itemFc.checkbox && itemFc.checkbox == true) { needRemove = true; }
                //hidden列
                if (!needRemove && itemFc.hidden && itemFc.hidden == true) { needRemove = true; }
                //无title的列、title过滤html标签后为空的列
                if (!needRemove && ($.string.isNullOrWhiteSpace(itemFc.title))) { needRemove = true; }
                if (!needRemove) {
                    itemFc.title = delHtmlTag(itemFc.title);
                    if ($.string.isNullOrWhiteSpace(itemFc.title)) { needRemove = true; }
                }

                if (needRemove) { fColumns[k].removeAt(inK); tempLen--; inK--; }
            }
        }
        //计算列集合的总列数总行数
        //总行数 = fColumns.length
        //总列数 = fColumns[item].colspan之和中最大的
        var colspanCount = $.array.max($.array.map(fColumns, function (itemFc) { return $.array.sum(itemFc, function (item) { return item.colspan || 1; }) })),
            rowspanCount = fColumns.length;

        var lastColumns = [];
        //组建最终列集合的数组结构
        for (var i = 0; i < rowspanCount; i++) {
            lastColumns[i] = new Array(colspanCount);
        }

        var getFixedColumnIndex = function (a) {
            for (var i = 0; i < a.length; i++) {
                if (a[i] == undefined) {
                    return i;
                }
            }
            return -1;
        };
        //往最终列集合里填充数据
        for (var columIndex = 0; columIndex < fColumns.length; columIndex++) {
            fColumns[columIndex].forEach(function (itemFc, itemIndex) {
                var fieldIndex = getFixedColumnIndex(lastColumns[columIndex]); //找到第一个未赋值的元素索引
                if (fieldIndex >= 0) {
                    for (var c = fieldIndex; c < colspanCount ; c++) {
                        var tempCol = $.extend({}, itemFc, {});
                        if (tempCol.colspan == undefined) { tempCol.colspan = 1; }
                        if (tempCol.rowspan == undefined) { tempCol.rowspan = 1; }
                        if ((itemFc.colspan || 1) > 1) {
                            //若列是跨列的，则认为该列的field无效
                            delete tempCol.field;
                        }
                        lastColumns[columIndex][c] = tempCol;
                        if ((itemFc.rowspan || 1) > 1) {
                            for (var d = 1; d < itemFc.rowspan; d++) {
                                if (columIndex + d <= rowspanCount) {
                                    lastColumns[columIndex + d][c] = $.extend({}, tempCol);
                                }
                            }
                        }
                        if ((itemFc.colspan || 1) > 1) {
                            for (var d = 1; d < itemFc.colspan; d++) {
                                if (c + d <= colspanCount) {
                                    lastColumns[columIndex][c + d] = $.extend({}, tempCol);
                                }
                            }
                        }
                        break;
                    }
                }
            });
        }

        return lastColumns;
    };

    var methods = {

        //  扩展 easyui-datagrid 的自定义方法；导出当前页数据到文件；该方法定义如下参数：
        //      param:  这是一个 JSON-Object 对象，该 JSON-Object 可以包含如下属性：
        //          fileType:        字符串，表示要导出的目标文件类型，其值可以是 excel ，若不传递该参数，则当做 excel ；
        //          fileName:        字符串，表示要导出的目标文件名称，若不传递该参数，则使用默认文件名；
        //          isAll:           Boolean值，是否导出全部而非仅当前页数据，如果不传入该参数默认为 false 即导出当前页数据。
        //                           当 isAll 为 true 时，需要当前 easyui-datagrid 控件的 url 属性指示的服务器数据源支持查询所有数据
        //                          （以 rows: 0 方式不分页查询所有数据）。
        //  返回值：返回表示当前 easyui-datagrid 控件的 jQuery 链式对象。
        exportData: function (jq, param) {
            return jq.each(function () {
                exportData(this, param);
            });
        }
    };

    if ($.fn.datagrid.extensions != null && $.fn.datagrid.extensions.methods != null) {
        $.extend($.fn.datagrid.extensions.methods, methods);
    }

    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.deleteRow.js
* 开发 流云
* 由 落阳 整理
* 最近更新：2015-11-21
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.findRow.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    $.fn.datagrid.extensions.deleteRow = $.fn.datagrid.methods.deleteRow;
    var deleteRow = function (target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options,
            row,index;
        if ($.util.isNumber(param)) {
            var rows = t.datagrid("getRows");
            row = $.array.first(rows, function (itemRow, itemIndex) { return itemIndex == param; });
            index = param;
        }
        else {
            row = t.datagrid("findRow", param);
            index = t.datagrid("getRowIndex", row);
        }
        if (index > -1 && $.isFunction(opts.onBeforeDeleteRow) && opts.onBeforeDeleteRow.call(target, index, row) == false) { return; }
        $.fn.datagrid.extensions.deleteRow.call(target, t, index);
        if ($.isFunction(opts.onDeleteRow)) { opts.onDeleteRow.call(target, index, row); }
    };

    var deleteRows = function (target, param) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        if ($.array.likeArrayNotString(param)) {
            $.each(param, function (index, val) { deleteRow(target, val); });
        } else if ($.isFunction(param)) {
            var rows = t.datagrid("getRows"), onBeforeDeleteRowExist = $.isFunction(opts.onBeforeDeleteRow), onDeleteRowExist = $.isFunction(opts.onDeleteRow);
            // 以下是“遍历rows，对每个row调用param回调函数，若返回true则删除行”的方式，但是每次deleteRow都将更新rows的索引
            //$.each(rows, function (index, row) {
            //    if (!row) { return; }
            //    if (param.call(target, row, index, rows) == true) {
            //        var i = t.datagrid("getRowIndex", row);
            //        if (i > -1 && onBeforeDeleteRowExist && opts.onBeforeDeleteRow.call(target, i, row) == false) { return; }
            //        $.fn.datagrid.extensions.deleteRow.call(target, t, i);
            //        if (onDeleteRowExist) { opts.onDeleteRow.call(target, i, row); }
            //    }
            //});
            // 以下是“调用findRows，将符合param回调函数的row组装成数组，最后遍历数组对每项进行删除行”的方式
            // 从常规逻辑来看，这种处理逻辑更合理
            var theRows = t.datagrid("findRows", param);
            $.each(theRows, function (index, row) {
                var i = t.datagrid("getRowIndex", row);
                if (i > -1 && onBeforeDeleteRowExist && opts.onBeforeDeleteRow.call(target, i, row) == false) { return; }
                $.fn.datagrid.extensions.deleteRow.call(target, t, i);
                if (onDeleteRowExist) { opts.onDeleteRow.call(target, i, row); }
            });
        }
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  重写 easyui-datagrid 的 deleteRow 方法；参数 param 表示要删除的内容；该参数可以是以下四种类型：
        //      Number 类型，表示要删除的行索引号，从 0 开始计数；
        //      表示要删除的行数据的 idField(主键) 字段值；
        //      行数据对象；
        //      Function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 Function 类型，则 deleteRow 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则表示查找到了需要被删除的行，deleteRow 方法将会删除该行数据并立即停止和跳出循环操作；
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        deleteRow: function (jq, param) { return jq.each(function () { deleteRow(this, param); }); },

        //  扩展 easyui-datagrid 的自定义方法；参数 param 表示要删除的内容；该参数可以是以下两种类型：
        //      Function 类型，该回调函数签名为 function(row, index, rows)，其中 row 表示行数据对象、index 表示行索引号、rows 表示当前 easyui-datagrid 调用 getRows 返回的结果集；
        //          如果 param 参数为 Function 类型，则 deleteRows 方法会对当前 easyui-datagrid 的当前页的每一行数据调用该回调函数；
        //          当回调函数返回 true 时，则表示查找到了需要被删除的行，deleteRows 方法将会删除该行数据，并遍历下一行数据直至数数据集的末尾；
        //      Array 类型，数组中的每一项目均表示要删除的行的行索引号或者 idField(主键) 字段值或者行数据对象
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        deleteRows: function (jq, param) { return jq.each(function () { deleteRows(this, param); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义事件；该事件表示执行 deleteRow 方法前所触发的动作；该事件回调函数提供如下两个参数：
        //      index:  表示要进行 deleteRow 的行的索引号，从 0 开始计数；
        //      row:    表示要进行 deleteRow 操作的行数据对象；
        //  该事件函数中的 this 指向当前 easyui-datarid 的 DOM 对象(非 jQuery 对象)；
        //  备注：如果该事件回调函数返回 false，则立即取消即将要执行的 deleteRow 操作。
        onBeforeDeleteRow: function (index, row) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示执行 deleteRow 方法后所触发的动作；该事件回调函数提供如下两个参数：
        //      index:  表示要进行 deleteRow 的行的索引号，从 0 开始计数；
        //      row:    表示要进行 deleteRow 操作的行数据对象；
        //  该事件函数中的 this 指向当前 easyui-datarid 的 DOM 对象(非 jQuery 对象)；
        onDeleteRow: function (index, row) { }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.appendRow.js
* 开发 落阳
* 最近更新：2018-01-17
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2018 Lixilin personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    $.fn.datagrid.extensions.appendRow = $.fn.datagrid.methods.appendRow;
    var appendRow = function (target, row) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        
        if ($.isFunction(opts.onBeforeAppendRow) && opts.onBeforeAppendRow.call(target, row) == false) { return; }
        $.fn.datagrid.extensions.appendRow.call(target, t, row);
        if ($.isFunction(opts.onAppendRow)) { opts.onAppendRow.call(target, row); }
    };

    var appendRows = function (target, rows) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;
        if ($.array.likeArrayNotString(rows)) {
            $.each(rows, function (index, val) { appendRow(target, val); });
        }
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  重写 easyui-datagrid 的 appendRow 方法；参数 row 表示要追加的数据行；
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        appendRow: function (jq, row) { return jq.each(function () { appendRow(this, row); }); },

        //  扩展 easyui-datagrid 的自定义方法；参数 rows 表示要追加的数据行数组；该参数是以下类型：
        //      Array 类型，数组中的每一项目均表示要追加的行数据对象
        //  返回值：返回表示当前 easyui-datagrid 组件的 jQuery 链式对象。
        appendRows: function (jq, rows) { return jq.each(function () { appendRows(this, rows); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

        //  扩展 easyui-datagrid 的自定义事件；该事件表示执行 appendRow 方法前所触发的动作；该事件回调函数提供如下参数：
        //      row:    表示要进行 appendRow 操作的行数据对象；
        //  该事件函数中的 this 指向当前 easyui-datarid 的 DOM 对象(非 jQuery 对象)；
        //  备注：如果该事件回调函数返回 false，则立即取消即将要执行的 appendRow 操作。
        onBeforeAppendRow: function (index, row) { },

        //  扩展 easyui-datagrid 的自定义事件；该事件表示执行 appendRow 方法后所触发的动作；该事件回调函数提供如下参数：
        //      row:    表示要进行 appendRow 操作的行数据对象；
        //  该事件函数中的 this 指向当前 easyui-datarid 的 DOM 对象(非 jQuery 对象)；
        onAppendRow: function (index, row) { }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);
/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.fixed.cellMerge.js
* 开发 落阳
* 最近更新：2017-11-22
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2017 Lixilin personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    $.extend($.fn.datagrid.extensions, {

        mergeRecordsPropertyName: "mergeRecords",

        mergeRangePositionsPropertyName: "mergePositions",

        mergeCells: $.fn.datagrid.methods.mergeCells,

        endEdit: $.fn.datagrid.methods.endEdit
    });

    var mergeCells = function (target, mergeInfo) {
        var t = $(target),
            opts = $.data(target, "datagrid").options;

        if (mergeInfo.rowspan == 1 && mergeInfo.colspan == 1) {
            return;
        }
        mergeInfo.type = mergeInfo.type || "body";
        var tr = opts.finder.getTr(target, (mergeInfo.index != undefined ? mergeInfo.index : mergeInfo.id), mergeInfo.type);
        if (!tr.length) {
            return;
        }
        //如果合并的行是横跨冻结列和常规列，则认为合并行为无效
        var frozenFields = t.datagrid("getColumnFields", true);
        var normalFields = t.datagrid("getColumnFields", false);
        var fieldIndex = getFieldIndex(frozenFields, normalFields, mergeInfo.field);
        if (fieldIndex.fieldIndexInFrozen != -1 && (fieldIndex.fieldIndexInFrozen + (mergeInfo.colspan || 1) - 1) > frozenFields.length - 1) {
            console.log("合并的行横跨冻结列和常规列，合并行为无效");
            return;
        }
        var ret = $.fn.datagrid.extensions.mergeCells.call(target, t, mergeInfo);

        if (!opts[$.fn.datagrid.extensions.mergeRecordsPropertyName]) { opts[$.fn.datagrid.extensions.mergeRecordsPropertyName] = []; }
        var theMergeInfo = {
            type: mergeInfo.type,
            rowspan: mergeInfo.rowspan || 1,
            colspan: mergeInfo.colspan || 1,
            field: mergeInfo.field,
            index: mergeInfo.index,
            id: mergeInfo.id
        };
        opts[$.fn.datagrid.extensions.mergeRecordsPropertyName].push(theMergeInfo);

        if (!opts[$.fn.datagrid.extensions.mergeRangePositionsPropertyName]) { opts[$.fn.datagrid.extensions.mergeRangePositionsPropertyName] = []; }

        opts[$.fn.datagrid.extensions.mergeRangePositionsPropertyName].push(getMergeRangePosition(target, opts, frozenFields, normalFields, theMergeInfo));

        return ret;
    };

    var getMergeRecords = function (target) {
        return $.data(target, "datagrid").options[$.fn.datagrid.extensions.mergeRecordsPropertyName] || [];
    };

    var getMergePositions = function (target) {
        return $.data(target, "datagrid").options[$.fn.datagrid.extensions.mergeRangePositionsPropertyName] || [];
    };

    var getMergeRangePosition = function (target, opts, frozenFields, normalFields, mergeInfo) {
        if (mergeInfo.type != "body") { return null; }

        var indexs = getFieldIndex(frozenFields, normalFields, mergeInfo.field);
        var fieldIndexInFrozen = indexs.fieldIndexInFrozen,
            fieldIndexInNormal = indexs.fieldIndexInNormal,
            fieldIndex = indexs.fieldIndex;

        var ranges = [];
        var beginRowIndex = mergeInfo.index, endRowIndex = beginRowIndex + mergeInfo.rowspan - 1;
        var beginFieldIndex = fieldIndex, endFieldIndex = beginFieldIndex + mergeInfo.colspan - 1;

        var crossFields = [];
        if (fieldIndexInFrozen != -1) {
            for (var i = fieldIndexInFrozen; i < frozenFields.length && i <= endFieldIndex; i++) {
                crossFields.push(frozenFields[i]);
            }
        } else {
            for (var i = fieldIndexInNormal; i < normalFields.length && i <= endFieldIndex; i++) {
                crossFields.push(normalFields[i]);
            }
        }

        return {
            beginRowIndex: beginRowIndex,
            endRowIndex: endRowIndex,
            beginFieldIndex: beginFieldIndex,
            endFieldIndex: endFieldIndex,
            beginField: mergeInfo.field,
            endField: crossFields[crossFields.length - 1],
            crossFields: crossFields
        };
    };

    var endEdit = function (target, index) {
        var t = $(target), opts = $.data(target, "datagrid").options,
            ret = $.fn.datagrid.extensions.endEdit.call(target, t, index);
        mergePositions = getMergePositions(target);

        if (!mergePositions.length) { return ret; }

        var frozenFields = t.datagrid("getColumnFields", true),
            normalFields = t.datagrid("getColumnFields", false);
        var rows = t.datagrid("getRows");

        $.array.forEach([frozenFields, normalFields], function (theFields) {
            $.array.forEach(theFields, function (field) {
                var column = t.datagrid('getColumnOption', field);
                if (!hasEditor(column, field)) { return; }
                console.log("列[" + field + "]存在编辑器");
                var rowIndex = index;
                var fieldIndex = getFieldIndex(frozenFields, normalFields, field).fieldIndex;
                for (var i = 0; i < mergePositions.length; i++) {
                    console.log("循环合并的单元格范围[" + i + "]");
                    var position = mergePositions[i];
                    if (position.beginRowIndex == rowIndex && position.beginFieldIndex == fieldIndex) {
                        console.log("当前数据行[" + rowIndex + "]当前数据列[" + field + "](" + fieldIndex + ")是循环范围对象[" + position.beginRowIndex + "," + position.beginFieldIndex + "]的开始坐标");
                        var value = (column.formatter && $.isFunction(column.formatter)) ? column.formatter.call(target, rows[rowIndex][field], rows[rowIndex], rowIndex) : rows[rowIndex][field];
                        console.log("当前单元格值：" + value);
                        console.log("开始设置循环范围内其他位置的单元格");
                        for (var tempRowIndex = position.beginRowIndex; tempRowIndex <= position.endRowIndex; tempRowIndex++) {
                            var tempRow = rows[tempRowIndex];
                            console.log("数据行[" + tempRowIndex + "]");
                            var needUpdate = false;
                            var needUpdateFields = [];
                            for (var tempFieldIndex = position.beginFieldIndex; tempFieldIndex <= position.endFieldIndex; tempFieldIndex++) {
                                if (tempRowIndex == rowIndex && tempFieldIndex == fieldIndex) { console.log("自己单元格，略过"); continue; }
                                needUpdate = true;
                                var tempField = position.crossFields[tempFieldIndex - position.beginFieldIndex];
                                console.log("数据列[" + tempField + "(" + tempFieldIndex + ")]");
                                needUpdateFields.push(tempField);
                                //3 4 5 6 7
                                //A B C D E
                                //3=>0
                                //4=>1
                                //5=>2
                                tempRow[tempField] = value;
                                var rowDom = getRowDom(target, tempRowIndex);
                                if (rowDom.hasClass("datagrid-row-editing")) {
                                    var editor = t.datagrid("getEditor", { index: tempRowIndex, field: tempField });
                                    if (editor) {
                                        editor.actions && editor.actions.setValue(editor.target[0], value);
                                    } else {
                                        var cellDom = getCellDom(target, { index: tempRowIndex, field: tempField });
                                        cellDom.html(value);
                                    }
                                } else {
                                    var cellDom = getCellDom(target, { index: tempRowIndex, field: tempField });
                                    cellDom.html(value);
                                }
                                console.log("预计设置：数据行[" + tempRowIndex + "]数据列[" + tempField + "(" + tempFieldIndex + ")]的value为[" + value + "]");
                            }
                            if (needUpdate) {
                                console.log("完成数据行更新：数据行[" + tempRowIndex + "]，数据列[" + needUpdateFields.join(",") + "]");
                            }
                        }
                    }
                }
            });
        });

        return ret;
    };

    var getFieldIndex = function (frozenFields, normalFields, field) {
        var fieldIndex = -1, fieldIndexInFrozen = -1, fieldIndexInNormal = -1;
        for (var i = 0; i < frozenFields.length; i++) {
            if (frozenFields[i] == field) { fieldIndexInFrozen = i; break; }
        }
        for (var i = 0; (fieldIndexInFrozen == -1 && i < normalFields.length) ; i++) {
            if (normalFields[i] == field) { fieldIndexInNormal = i; break; }
        }
        fieldIndex = fieldIndexInFrozen != -1 ? fieldIndexInFrozen : (frozenFields.length + fieldIndexInNormal);

        return {
            fieldIndexInFrozen: fieldIndexInFrozen,
            fieldIndexInNormal: fieldIndexInNormal,
            fieldIndex: fieldIndex
        };
    };

    var hasEditor = function (column, field) {
        if (!column.editor) { return false; }

        var flag = typeof (column.editor) == "string", editorType = flag ? column.editor : column.editor.type, editorAction = $.fn.datagrid.defaults.editors[editorType];
        if (!editorAction) { editorType = undefined; }
        if (!editorType) { return false; }

        return true;
    };

    var getRowDom = function (target, index) {
        if (!$.isNumeric(index) || index < 0) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel");
        return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "]");
    };

    var getColumnDom = function (target, param) {
        if ($.string.isNullOrEmpty(param)) { return $(); }
        var t = $(target), panel = t.datagrid("getPanel"),
            isObject = !$.string.isString(param),
            field = isObject ? param.field : param,
            header = isObject ? param.header : false,
            dom = panel.find("div.datagrid-view tr.datagrid-row td[field=" + field + "]");
        if (header) { dom = dom.add(panel.find("div.datagrid-view tr.datagrid-header-row td[field=" + field + "]")); }
        return dom;
    };

    var getCellDom = function (target, pos) {
        if (!pos || !pos.field || !$.isNumeric(pos.index) || pos.index < 0) { return $(); }
        var tr = getColumnDom(target, pos.index);
        return tr.find("td[field=" + pos.field + "] .datagrid-cell");
    };

    var methods = $.fn.datagrid.extensions.methods = {

        //  重写 easyui-datagrid 的原生方法 mergeCells ，以支持“合并单元格情况下的编辑操作同时生效到被合并的单元格”的扩展；
        mergeCells: function (jq, fields) { return jq.each(function () { mergeCells(this, fields); }); },

        //  重写 easyui-datagrid 的原生方法 endEdit ，以支持“合并单元格情况下的编辑操作同时生效到被合并的单元格”的扩展；
        endEdit: function (jq, index) { return jq.each(function () { endEdit(this, index); }); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中进行过合并单元格操作的记录数据所构成的一个数组；
        //  返回值：返回一个数组，数组中每一个元素都是合并单元格操作的参数对象，如果从未进行过合并单元格操作，则返回1个空数组
        getMergeRecords: function (jq) { return getMergeRecords(jq[0]); },

        //  扩展 easyui-datagrid 的自定义方法；获取 easyui-datagrid 中进行过合并单元格操作的单元格范围坐标所构成的一个数组；
        //  返回值：返回一个数组，数组中每一个元素都是合并单元格操作所影响的单元格范围坐标对象，如果从未进行过合并单元格操作，则返回1个空数组
        getMergePositions: function (jq) { return getMergePositions(jq[0]); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {

    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);
  /**
   * jQuery EasyUI 1.4.3
   * Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
   *
   * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
   * To use it on other terms please contact us at info@jeasyui.com
   * http://www.jeasyui.com/license_commercial.php
   *
   * jQuery EasyUI datagrid 组件扩展
   * jeasyui.extensions.datagrid.extEdit.js
   * 开发 流云
   * 由 落阳 整理
   * 最近更新：2015-12-02
   *
   * 依赖项：
   *   1、jquery.jdirk.js
   *   2、jeasyui.extensions.datagrid.editors.js
   *
   * Copyright (c) 2015 ChenJianwei personal All rights reserved.
   */
  (function () {

      $.util.namespace("$.fn.datagrid.extensions");

      var _originalMethod = {};

      $.extend(_originalMethod, {

          beginEdit: $.fn.datagrid.methods.beginEdit,

          endEdit: $.fn.datagrid.methods.endEdit,

          cancelEdit: $.fn.datagrid.methods.cancelEdit
      });


      function getRowDom(target, index) {
          if (!$.isNumeric(index) || index < 0) { return $(); }
          var t = $(target), panel = t.datagrid("getPanel");
          return panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "]");


          var t = $(target),
              p = t.datagrid("getPanel");
          return p.find("div.datagrid-view div.datagrid-body table.datagrid-btable tr.datagrid-row[datagrid-row-index=" + index + "]");
      }

      function beginEdit(target, index) {
          var t = $(target),
              ret = _originalMethod.beginEdit.call(t, t, index);
          setSingleEditing(target, index);
          createRowExtEditor(target, index);
          setRowEditorFocus(target, index);
          return ret;
      }

      function endEdit(target, index) {
          var t = $(target),
              ret = _originalMethod.endEdit.call(t, t, index);
          if (t.datagrid("validateRow", index)) {
              disposeRowExtEditor(target, index);
          }
          return ret;
      }

      function cancelEdit(target, index) {
          var t = $(target),
              ret = _originalMethod.cancelEdit.call(t, t, index);
          disposeRowExtEditor(target, index);
          return ret;
      }


      function createRowExtEditor(target, index) {
          var state = $.data(target, "datagrid"),
              opts = state.options;
          if (!opts.extEditing) { return; }
          var tr = getRowDom(target, index);
          if (!tr || !tr.length) { return; }
          var t = $(target),
              p = t.datagrid("getPanel"),
              v = p.find("div.datagrid-view"),
              v1 = v.find("div.datagrid-view1"),
              v2 = v.find("div.datagrid-view2"),
              b = v2.find("div.datagrid-body").addClass("datagrid-body-rowediting"),
              width = v1.outerWidth(),
              height = tr.outerHeight(),
              pos = tr.position(),
              top = pos.top + height + b.scrollTop() - v2.find("div.datagrid-header").outerHeight(),
              d = $("<div class=\"dialog-button datagrid-rowediting-panel\"></div>").appendTo(b).css("top", top).attr("datagrid-row-index", index);

          $("<a></a>").appendTo(d).linkbutton({
              plain: false, iconCls: "icon-ok",
              text: "保存"
          }).click(function () {
              endEdit(target, index);
          });
          $("<a></a>").appendTo(d).linkbutton({
              plain: false,
              iconCls: "icon-cancel",
              text: "取消"
          }).click(function () {
              cancelEdit(target, index);
          });

          var diff = (p.outerWidth() - d.outerWidth()) / 2 - width,
              left = diff > 0 ? diff : 0;
          d.css("left", left);
      }

      function disposeRowExtEditor(target, index) {
          var b = $(target).datagrid("getPanel").find("div.datagrid-view div.datagrid-view2 div.datagrid-body");
          if (!b.length) { return; }
          var d = b.find("div.datagrid-rowediting-panel[datagrid-row-index=" + index + "]").remove();
          if (!b.find("div.datagrid-rowediting-panel[datagrid-row-index]").length) {
              b.removeClass("datagrid-body-rowediting");
          }
      }

      function setSingleEditing(target, index) {
          var t = $(target),
              state = $.data(target, "datagrid"),
              opts = state.options;
          if (opts.singleEditing && (state.lastEditIndex != null && state.lastEditIndex != undefined && state.lastEditIndex != index)) {
              endEdit(target, state.lastEditIndex);
          }
          state.lastEditIndex = index;
      }

      function setRowEditorFocus(target, index) {
          var t = $(target),
              state = $.data(target, "datagrid"),
              opts = state.options;
          if (opts.autoFocusField) {
              var editors = t.datagrid("getEditors", index);
              if (editors.length) {
                  var editor = $.array.first(editors, function (val) { return val.field == opts.autoFocusField; });
                  if (!editor) {
                      editor = editors[0];
                  }
                  if (editor) {
                      $.util.delay(function () {
                          setEditorFocus(editor);
                      });
                  }
              }
          }
      }

      function setEditorFocus(editor) {
          if (!editor || !editor.target || !editor.target.length) {
              return;
          }
          if (editor.actions && $.isFunction(editor.actions.setFocus)) {
              if (editor.actions.focusable == undefined || ($.isFunction(editor.actions.focusable) && editor.actions.focusable(editor.target[0]) == true)) {
                  editor.actions.setFocus(editor.target[0]);
              }
          } else {
              if (editor.target.is(":hidden")) {
                  if ($.easyui.isComponent(editor.target, "textbox")) {
                      editor.target.textbox("textbox").focus();
                  }
              } else {
                  editor.target.focus();
              }
          }
      }


      var methods = {

          //  重写 easyui-datagrid 的原生方法 beginEdit ，以支持自定义属性 extEditing、singleEditing、autoFocusField 的扩展功能；
          beginEdit: function (jq, index) { return jq.each(function () { beginEdit(this, index); }); },

          //  重写 easyui-datagrid 的原生方法 endEdit ，以支持自定义属性 extEditing 的扩展功能；
          endEdit: function (jq, index) { return jq.each(function () { endEdit(this, index); }); },

          //  重写 easyui-datagrid 的原生方法 cancelEdit ，以支持自定义属性 extEditing 的扩展功能；
          cancelEdit: function (jq, index) { return jq.each(function () { cancelEdit(this, index); }); }
      };

      var defaults = {

          //  扩展 easyui-datagrid 的自定义属性，该属性表示在触发 beginEdit 事件后，是否构建仿 ext-grid-rowediting 行编辑的“保存”和“取消”按钮面板；
          //  Boolean 类型值，默认为 true。
          extEditing: true,

          //  扩展 easyui-datagrid 的自定义属性，该属性表示在一个时刻是否只允许一行数据开启编辑状态(当某行数据开启编辑状态时，其他正在编辑的行将会被自动执行 endEdit 操作)；
          //  Boolean 类型值，默认为 true。
          singleEditing: true,

          //  扩展 easyui-datagrid 的自定义属性，该属性表示在对某行执行 beginEdit 后，是否让特定字段的编辑器对象自动获取输入焦点；
          //  该属性可以为 Boolean（默认，true） 类型或者 String 类型值；
          //  如果是 Boolean 类型，则表示是否启用编辑器对象自动获取焦点功能，在值为 true 的情况下该行的第一个编辑器对象将在 beginEdit 操作后自动获取焦点；
          //  如果是 String 类型，其值表示指定的 field 名称，则表示启用该功能并且指定的 field 将在 beginEdit 操作后自动获取焦点。
          autoFocusField: true
      };

      if ($.fn.datagrid.extensions.defaults) {
          $.extend($.fn.datagrid.extensions.defaults, defaults);
      } else {
          $.fn.datagrid.extensions.defaults = defaults;
      }

      if ($.fn.datagrid.extensions.methods) {
          $.extend($.fn.datagrid.extensions.methods, methods);
      } else {
          $.fn.datagrid.extensions.methods = methods;
      }

      $.extend($.fn.datagrid.defaults, defaults);
      $.extend($.fn.datagrid.methods, methods);

  })(jQuery);

/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 编辑器扩展-回车聚焦
* jeasyui.extensions.datagrid.edit.enterFocus.js
* 开发 落阳
* 最近更新：2017-03-21
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.rowState.js
*   3、jeasyui.extensions.datagrid.editors.js
*   4、jeasyui.extensions.datagrid.getColumnInfo.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    var editorAvailable = function (target, field) {
        var t = $(target), opts = t.datagrid('options'), col = t.datagrid('getColumnOption', field);
        if (!col.editor) { return false; }

        var flag = typeof (col.editor) == "string", editorType = flag ? col.editor : col.editor.type, editorAction = $.fn.datagrid.defaults.editors[editorType];
        if (!editorAction) { editorType = undefined; }
        if (!editorType) { return false; }

        if (flag) { return true; } else {
            return col.editor.options == undefined ? true : (!(col.editor.options.readonly || col.editor.disabled));
        }
    };

    //找到第一个设置了编辑器并且编辑器可用的列的列名
    var getFirstAvailableEditorField = function (target) {
        return $(target).datagrid("getColumnFields", "all").first(function (item) { return editorAvailable(target, item); });
    };

    //自动聚焦到下一个列编辑器
    //t：datagrid-jquery对象
    //opts：datagrid-options对象
    //thisArg：jQ对象，可以是 editor、editor的容器（因为editor可能不存在）
    //field：列名
    //index：索引号，寻找同行的下一列编辑器时可传递，其他时候不能传递，需根据thisArg去获取
    var autoNextFieldEditorFocus = function (t, opts, thisArg, field, index) {
        //console.log("整行编辑：定位下一个编辑器");
        var panel = t.datagrid("getPanel"),
            index = index == undefined ? window.parseInt(thisArg.closest("tr[datagrid-row-index]").attr("datagrid-row-index")) : index;
        //console.log("当前列名：" + field);
        //console.log("当前索引：" + index);
        var cellTd = panel.find("div.datagrid-view div.datagrid-body table tr.datagrid-row[datagrid-row-index=" + index + "] td[field=" + field + "]");
        var nextCellTd = cellTd.next();
        if (nextCellTd.length == 0) {
            //下一个列的容器td不存在，视为本行编辑列到达结尾，结束本行编辑
            //console.log("下一个列的容器td不存在，视为本行编辑列到达结尾，结束本行编辑");
            t.datagrid("endEdit", index);

            var rows = t.datagrid("getRows");
            if (!rows || !rows.length) { return; }
            var len = rows.length;
            if (index < len - 1) {
                if (!t.datagrid("isEditing", index + 1)) {
                    t.datagrid("beginEdit", index + 1); 
                } else {
                    var editableField = getFirstAvailableEditorField(t);
                    if (!editableField) {
                        return;
                    }
                    var editorNextRow = t.datagrid("getEditor", { field: editableField, index: index + 1 });
                    if (editorNextRow.actions && $.isFunction(editorNextRow.actions.setFocus)) {
                        if ($.isFunction(editorNextRow.actions.focusable) && editorNextRow.actions.focusable(editorNextRow.target[0]) == true) {
                            editorNextRow.actions.setFocus(editorNextRow.target[0]);
                        }
                        else {
                            //不可聚焦，这不科学
                        }
                    } else {
                        editorNextRow.target.focus();
                    }
                }
            } else {
                opts.onAfterFoucsLastEditor.call(t[0], index, field);
            }

            return;
        }
        var nextField = nextCellTd.attr("field"),
            nextCell = nextCellTd.find("div.datagrid-cell"),
            editor = t.datagrid("getEditor", { field: nextField, index: index });
        if (!editor) {
            //下一个列的editor不存在，说明该列无编辑器，寻找下一个列的editor
            //console.log("下一个列的editor不存在，说明该列无编辑器，寻找下一个列的editor");
            autoNextFieldEditorFocus(t, opts, nextCell, nextField, index);
        }
        else {
            if (editor.actions && $.isFunction(editor.actions.setFocus)) {
                if ($.isFunction(editor.actions.focusable) && editor.actions.focusable(editor.target[0]) == true) {
                    editor.actions.setFocus(editor.target[0]);
                }
                else {
                    //不可聚焦，跳过，寻找下一个列的editor
                    //console.log("不可聚焦，跳过，寻找下一个列的editor");
                    autoNextFieldEditorFocus(t, opts, editor.target, nextField, index);
                }
            } else {
                editor.target.focus();
            }
        }
    }

    //绑定“自动聚焦下一个列的编辑器”事件
    //t：datagrid-jquery对象
    //opts：datagrid-options对象
    //input：输入框jquery对象
    //field：当前在编辑的列名
    var bindAutoFocusNextFieldEditor = function (t, opts, input, field) {
        input.keydown(function (e) {
            if (e.which == 13) {
                var val = $(this).val();
                if (opts.stopEnterFocusWhenEmpty && $.string.isNullOrWhiteSpace(val)) { return; }
                autoNextFieldEditorFocus(t, opts, $(this), field);
            }
        });
    };

    // 初始化事件绑定
    function initExtendEventBind(t, opts) {

        if (opts.enterFocusNextEditor) {
            //开始编辑事件
            var _onBeginEdit = opts.onBeginEdit;
            opts.onBeginEdit = function (index, row) {
                if ($.isFunction(_onBeginEdit)) { _onBeginEdit.call(this, index, row); }

                var fields = t.datagrid("getColumnFields", "all"), editors = fields.map(function (item) { return t.datagrid("getEditor", { index: index, field: item }); });
                if (editors.length == 0) { return; }
                
                editors.forEach(function (item) {
                    if (!item) { return; }
                    if (item.actions && $.isFunction(item.actions.input)) {
                        var theInput = item.actions.input(item.target[0]);
                        bindAutoFocusNextFieldEditor(t, opts, theInput, item.field);
                    } else {
                        bindAutoFocusNextFieldEditor(t, opts, item.target, item.field);
                    }
                });

                $.util.delay(function () {
                    //自动聚焦第一个可聚焦的编辑器
                    for (var i = 0; i < editors.length; i++) {
                        var editor = editors[i];
                        if (!editor) { continue; }
                        if (editor.actions && $.isFunction(editor.actions.setFocus)) {
                            if ($.isFunction(editor.actions.focusable) && editor.actions.focusable(editor.target[0]) == true) {
                                editor.actions.setFocus(editor.target[0]); break;
                            }
                            else {
                                //不可聚焦，跳过
                            }
                        } else {
                            editor.target.focus(); break;
                        }
                    }
                });
            };
        }
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initExtendEventBind(t, opts);
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this, [
                            {
                                enterFocusNextEditor: "boolean",
                                stopEnterFocusWhenEmpty: "boolean"
                            }
                        ]), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);


    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；检查指定列是否配置了可用（非只读且未禁用）编辑器；该方法定义如下参数：
        //      field: 列的 field 名；
        //  返回值：若指定列配置了可用（非只读且未禁用）编辑器则返回 true ，否则返回 false 。
        editorAvailable: function (jq, field) { return editorAvailable(jq[0], field); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {


        //  扩展 easyui-datagrid 的自定义属性；表示开启编辑后是否启用回车后自动聚焦下一个列编辑器的功能；
        //  Boolean 类型值，默认 true。
        enterFocusNextEditor: true,

        //  扩展 easyui-datagrid 的自定义属性；表示在 autoFocusNextFieldEditor 为 true 的前提下，当前编辑器内容若为空，是否停止回车聚焦功能；
        //  Boolean 类型值，默认 false。
        stopEnterFocusWhenEmpty: false,

        //  扩展 easyui-datagrid 的自定义事件；表示聚焦到最后一个单元格编辑器之后触发的事件；该事件定义如下参数：
        //      index: 数据行的索引；
        //      field: 列的 field 名；
        //  注意，该事件接口是指“聚焦到最后一行最后一个单元格编辑器之后触发的事件”，并不是每个数据行的最后一个单元格编辑器聚焦后触发。
        onAfterFoucsLastEditor: function (index, field) { }
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);



/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 编辑器扩展-回车聚焦
* jeasyui.extensions.datagrid.edit.cellEdit.js
* 开发 落阳
* 最近更新：2017-03-21
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.editors.js
*   3、jeasyui.extensions.datagrid.getColumnInfo.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");

    var editCell = function (target, param) {
        if (!param || !param.field || param.index == undefined || param.index == null) { return; }
        var t = $(target), opts = t.datagrid('options'), fields = t.datagrid("getColumnFields", "all");
        for (var i = 0; i < fields.length; i++) {
            var col = t.datagrid('getColumnOption', fields[i]);
            col.editor1 = col.editor;
            if (fields[i] != param.field) {
                col.editor = null;
            }
        }
        opts.editIndex = param.index; opts.editField = param.field;
        t.datagrid('beginEdit', param.index);
        var ed = t.datagrid('getEditor', param);
        if (ed) {
            //尝试聚焦
            var editorTarget = ed.target[0];
            if ($.isFunction(ed.actions.focusable)) {
                if (ed.actions.focusable(editorTarget) == true) {
                    if ($.isFunction(ed.actions.setFocus)) {
                        ed.actions.setFocus(editorTarget);
                    } else {
                        var theInput = $.isFunction(ed.actions.input) ? ed.actions.input(editorTarget) : ed.target;
                        theInput.focus();
                    }
                } else {
                    //不可聚焦
                }
            }
            else {
                var theInput = $.isFunction(ed.actions.input) ? ed.actions.input(editorTarget) : ed.target;
                theInput.focus();
            }
        }
        for (var i = 0; i < fields.length; i++) {
            var col = t.datagrid('getColumnOption', fields[i]);
            col.editor = col.editor1;
        }
    };

    // 初始化事件绑定
    function initExtendEventBind(t, opts) {

        if (opts.enableCellEdit) {
            //单元格点击事件
            var _onClickCell = opts.onClickCell;
            opts.onClickCell = function (index, field) {
                if ($.isFunction(_onClickCell)) { _onClickCell.call(this, index, field); }
                //console.log("内置事单元格点击件" + field);
                if (opts.editIndex != undefined && opts.editIndex != null) {
                    if (t.datagrid('validateRow', opts.editIndex)) {
                        t.datagrid('endEdit', opts.editIndex);
                    } else {
                        return;
                    }
                }
                opts.editIndex = index;
                opts.editField = field;
                editCell(t[0], { index: index, field: field });
            };

            //结束编辑事件
            var _onEndEdit = opts.onEndEdit;
            opts.onEndEdit = function (index, row, changes) {
                if ($.isFunction(_onEndEdit)) { _onEndEdit.call(this, index, row, changes); }
                opts.editIndex = undefined; opts.editField = undefined;
            };
        }
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initExtendEventBind(t, opts);
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this, [
                            {
                                enableCellEdit: "boolean"
                            }
                        ]), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);


    var methods = $.fn.datagrid.extensions.methods = {

        //  扩展 easyui-datagrid 的自定义方法；开启指定单元格的编辑状态；该方法定义如下参数：
        //      param:  这是一个 JSON-Object 对象，该对象定义如下属性：
        //          index: 要开启编辑的数据行的索引号，从 0 开始计数；
        //          field: 要开启编辑的数据的列的 field 名；
        //  返回值：返回表示当前 easyui-datagrid 控件的 jQuery 链式对象；
        editCell: function (jq, param) { return jq.each(function () { editCell(this, param); }); }
    };

    var defaults = $.fn.datagrid.extensions.defaults = {


        //  扩展 easyui-datagrid 的自定义属性；表示是否开启单元格编辑功能；
        //  Boolean 类型值，默认 false。
        enableCellEdit: false
    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 组件扩展
* jeasyui.extensions.datagrid.editors.js
* 开发 流云
* 由 落阳 整理和二次扩展
* 最近更新：2015-12-03
*
* 依赖项：
*   1、jquery.jdirk.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function ($) {

    var editors = $.fn.datagrid.defaults.editors,
        text_init = editors.text.init,
        textarea_init = editors.textarea.init,
        checkbox_init = editors.checkbox.init,
        textbox_init = editors.textbox.init,
        validatebox_init = editors.validatebox.init,
        numberbox_init = editors.numberbox.init,
        datebox_init = editors.datebox.init,
        combobox_init = editors.combobox.init,
        combotree_init = editors.combotree.init;


    //  扩展 easyui-datagrid editors-text 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.text, {
        setFocus: function (target) {
            $(target).focus();
        },
        focusable: function (target) {
            return true;
        },
        input: function (target) {
            return $(target);
        }
    });

    //  扩展 easyui-datagrid editors-textarea 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.textarea, {
        setFocus: function (target) {
            $(target).focus();
        },
        focusable: function (target) {
            return true;
        },
        input: function (target) {
            return $(target);
        }
    });

    //  扩展 easyui-datagrid editors-checkbox 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.checkbox, {
        init: function (container, options) {
            return checkbox_init.apply(this, arguments).addClass("datagrid-editable-input datagrid-editable-checkbox");
        },
        setFocus: function (target) {
            $(target).focus();
        },
        focusable: function (target) {
            return true;
        },
        input: function (target) {
            return $(target);
        }
    });

    //  扩展 easyui-datagrid editors-validatebox 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.validatebox, {
        setFocus: function (target) {
            $(target).focus();
        },
        focusable: function (target) {
            var t = $(target), opts = t.validatebox("options");
            return !(opts.disabled || opts.readonly);
        },
        input: function (target) {
            return $(target);
        }
    });

    //  扩展 easyui-datagrid editors-textbox 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.textbox, {
        init: function (container, options) {
            var box = textbox_init.apply(this, arguments);
            box.textbox("textbox").addClass("datagrid-editable-input");
            return box;
        },
        setFocus: function (target) {
            $(target).textbox("textbox").focus();
        },
        focusable: function (target) {
            var t = $(target), opts = t.textbox("options");
            return !(opts.disabled || !opts.editable || opts.readonly);
        },
        input: function (target) {
            return $(target).textbox("textbox");
        }
    });

    //  扩展 easyui-datagrid editors-numberbox 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.numberbox, {
        init: function (container, options) {
            var box = numberbox_init.apply(this, arguments);
            box.numberbox("textbox").addClass("datagrid-editable-input");
            return box;
        },
        setFocus: function (target) {
            $(target).numberbox("textbox").focus();
        },
        focusable: function (target) {
            var t = $(target), opts = t.numberbox("options");
            return !(opts.disabled || !opts.editable || opts.readonly);
        },
        input: function (target) {
            return $(target).numberbox("textbox");
        }
    });

    //  扩展 easyui-datagrid editors-datebox 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.datebox, {
        init: function (container, options) {
            var box = datebox_init.apply(this, arguments);
            box.datebox("textbox").addClass("datagrid-editable-input");
            return box;
        },
        setFocus: function (target) {
            $(target).datebox("textbox").focus();
        },
        focusable: function (target) {
            var t = $(target), opts = t.datebox("options");
            return !(opts.disabled || !opts.editable || opts.readonly);
        },
        input: function (target) {
            return $(target).datebox("textbox");
        }
    });

    //  扩展 easyui-datagrid editors-combobox 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.combobox, {
        init: function (container, options) {
            var box = combobox_init.apply(this, arguments);
            box.combobox("textbox").addClass("datagrid-editable-input");
            return box;
        },
        setFocus: function (target) {
            $(target).combobox("textbox").focus();
        },
        focusable: function (target) {
            var t = $(target), opts = t.combobox("options");
            return !(opts.disabled || !opts.editable || opts.readonly);
        },
        input: function (target) {
            return $(target).combobox("textbox");
        }
    });

    //  扩展 easyui-datagrid editors-combotree 的自定义方法；
    //  setFocus，该方法用于聚焦当前编辑控件；
    //  focusable，该方法用于检查当前编辑控件是否可聚焦；
    //  input，该方法用于返回输入框对象；
    $.extend(editors.combotree, {
        init: function (container, options) {
            var box = combotree_init.apply(this, arguments);
            box.combotree("textbox").addClass("datagrid-editable-input");
            return box;
        },
        setFocus: function (target) {
            $(target).combotree("textbox").focus();
        },
        focusable: function (target) {
            var t = $(target), opts = t.combotree("options");
            return !(opts.disabled || !opts.editable || opts.readonly);
        },
        input: function (target) {
            return $(target).combotree("textbox");
        }
    });

})(jQuery);


/**
* jQuery EasyUI 1.4.3
* Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
*
* Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
* To use it on other terms please contact us at info@jeasyui.com
* http://www.jeasyui.com/license_commercial.php
*
* jQuery EasyUI datagrid 编辑器扩展-回车聚焦
* jeasyui.extensions.datagrid.edit.autoCount.js
* 开发 落阳
* 最近更新：2017-03-21
*
* 依赖项：
*   1、jquery.jdirk.js
*   2、jeasyui.extensions.datagrid.rowState.js
*   3、jeasyui.extensions.datagrid.editors.js
*   4、jeasyui.extensions.datagrid.getColumnInfo.js
*
* Copyright (c) 2015 ChenJianwei personal All rights reserved.
*/
(function () {

    $.util.namespace("$.fn.datagrid.extensions");


    //获取其他行的指定列之和
    //t：datagrid-jquery对象
    //opts：datagrid-options对象
    //field：要计算的列名
    //exceptRowIndex：要排除的数据行索引
    var getOtherRowsTotal = function (t, opts, field, exceptRowIndex) {
        var rows = t.datagrid("getRows"), len = rows.length, total = 0;
        for (var i = 0; i < len; i++) {
            if (i == exceptRowIndex) { continue; }
            if (t.datagrid("isEditing", i)) {
                var editor = t.datagrid("getEditor", { index: i, field: field });
                if (editor) {
                    var val = editor.actions ? editor.actions.getValue(editor.target[0]) : editor.target.val();
                    if (!$.string.isNullOrWhiteSpace(val)) { total += Number(val); }
                } else {
                    var val = rows[i][field];
                    if (!$.string.isNullOrWhiteSpace(val)) { total += Number(val); }
                }
            }
            else {
                var val = rows[i][field];
                if (!$.string.isNullOrWhiteSpace(val)) { total += Number(val); }
            }
        }

        return total;
    };

    //更新合计行
    //t：datagrid-jquery对象
    //opts：datagrid-options对象
    //totalField：显示合计值的列名
    //total：合计值
    var updateFooter = function (t, opts, totalField, total) {
        var footerRows = t.datagrid("getFooterRows");
        footerRows.forEach(function (row) {
            var temp = {};
            temp[totalField] = total;
            $.extend(row, temp);
        });
        t.datagrid('reloadFooter', footerRows);
    };

    //计算统计行
    //t：datagrid-jquery对象
    //opts：datagrid-options对象
    //index：要排除计算的数据行索引
    //field：要计算的列名
    var calcToFooter = function (t, opts, index, field) {
        var val = $(this).val(), otherCountTotal = getOtherRowsTotal(t, opts, field, index);
        var total = $.string.isNullOrWhiteSpace(val) ? otherCountTotal : (Number(val) + otherCountTotal);
        updateFooter(t, opts, field, total);
    };

    //绑定自动计算事件
    //t：datagrid-jquery对象
    //opts：datagrid-options对象
    //input：输入框jquery对象
    //index：要排除计算的数据行索引
    //field：要计算的列名
    var bindCalcEvent = function (t, opts, input, index, field) {
        var colOpts = t.datagrid("getColumnOption", field);
        if (colOpts.calcable) {
            input.keyup(function () {
                calcToFooter.call(this, t, opts, index, field);
            });
        }
    };




    // 初始化事件绑定
    function initExtendEventBind(t, opts) {

        //开始编辑事件
        var _onBeginEdit = opts.onBeginEdit;
        opts.onBeginEdit = function (index, row) {
            if ($.isFunction(_onBeginEdit)) { _onBeginEdit.call(this, index, row); }

            var fields = t.datagrid("getColumnFields", "all"), editors = fields.map(function (item) { return t.datagrid("getEditor", { index: index, field: item }); });
            if (editors.length == 0) { return; }

            editors.forEach(function (item) {
                if (!item) { return; }
                if (item.actions && $.isFunction(item.actions.input)) {
                    var theInput = item.actions.input(item.target[0]);
                    bindCalcEvent(t, opts, theInput, index, item.field);
                } else {
                    bindCalcEvent(t, opts, item.target, index, item.field);
                }
            });
        };
    }

    // 初始化列 options 扩展属性
    function initExtendColumnOptions(t, opts) {
        var target = t[0],
            state = $.data(target, "datagrid"),
            cols = t.datagrid("getColumnOptions", "all");
        $.each(cols, function (i, col) {
            $.union(col, $.fn.datagrid.extensions.columnOptions);
        });
    }

    function initializeExtensions(target) {
        var t = $(target),
            state = $.data(target, "datagrid"),
            opts = state.options;

        initExtendColumnOptions(t, opts);
        initExtendEventBind(t, opts);
    }

    var _datagrid = $.fn.datagrid.extensions._datagrid = $.fn.datagrid;
    $.fn.datagrid = function (options, param) {
        if (typeof options == "string") {
            return _datagrid.apply(this, arguments);
        }
        options = options || {};
        return this.each(function () {
            var jq = $(this),
                isInited = $.data(this, "datagrid") ? true : false,
                opts = isInited ? options : $.extend({},
                        $.fn.datagrid.parseOptions(this),
                        $.parser.parseOptions(this, []), options);
            _datagrid.call(jq, opts, param);
            if (!isInited) {
                initializeExtensions(this);
            }
        });
    };
    $.union($.fn.datagrid, _datagrid);


    var columnOptions = {

        // 表示该列是否可计算，其值可以是 Boolean 类型；
        // 默认为 false。
        // 该属性用于在“自动纵向统计”时使用。
        calcable: false
    };
    	
    
    if ($.fn.datagrid.extensions.columnOptions) {
        $.extend($.fn.datagrid.extensions.columnOptions, columnOptions);
    }
    else {
        $.fn.datagrid.extensions.columnOptions = columnOptions;
    }
    
    var methods = $.fn.datagrid.extensions.methods = {

        
    };

    var defaults = $.fn.datagrid.extensions.defaults = {


    };

    $.extend($.fn.datagrid.defaults, defaults);
    $.extend($.fn.datagrid.methods, methods);

})(jQuery);

  /**
   * 使datagrid的列中能显示row中的对象里的属性
   * Field：Staff.JoinDate
   **/
  (function () {

      $.util.namespace("$.fn.datagrid.extensions");
      var _renderRow = function (target, fields, frozen, rowIndex, rowData) {
          var opts = $.data(target, 'datagrid').options;
          var cc = [];
          if (frozen && opts.rownumbers) {
              var cellRownumber = rowIndex + 1;
              if (opts.pagination) {
                  cellRownumber += (opts.pageNumber - 1) * opts.pageSize;
              }
              cc.push("<td class=\"datagrid-td-rownumber\"><div class=\"datagrid-cell-rownumber\">"   + cellRownumber + "</div></td>");
          }
          for (var i = 0; i < fields.length; i++) {
              var field = fields[i];
              var col = $(target).datagrid("getColumnOption", field);
              if (col) {
                  var cellValue = getRowFieldData(rowData,field);

                  var colStyler = col.styler ? (col.styler(cellValue, rowData, rowIndex) || "")   : "";
                  var colStylerStr = col.hidden ? "style=\"display:none;" + colStyler  + "\"" : (colStyler ? "style=\"" + colStyler + "\"" : "");
                  cc.push("<td field=\"" + field + "\" " + colStylerStr + ">");
                  if (col.checkbox) {
                      var colStylerStr = "";
                  } else {
                      var colStylerStr = "";
                      if (col.align) {
                          colStylerStr += "text-align:" + col.align + ";";
                      }
                      if (!opts.nowrap) {
                          colStylerStr += "white-space:normal;height:auto;";
                      } else {
                          if (opts.autoRowHeight) {
                              colStylerStr += "height:auto;";
                          }
                      }
                  }
                  cc.push("<div style=\"" + colStylerStr + "\" ");
                  if (col.checkbox) {
                      cc.push("class=\"datagrid-cell-check ");
                  } else {
                      cc.push("class=\"datagrid-cell " + col.cellClass);
                  }
                  cc.push("\">");
                  if (col.checkbox) {
                      cc.push("<input type=\"checkbox\" name=\"" + field
                          + "\" value=\""
                          + (cellValue != undefined ? cellValue : "") + "\"/>");
                  } else {
                      if (col.formatter) {
                          cc.push(col.formatter(cellValue, rowData, rowIndex));
                      } else {
                          cc.push(cellValue);
                      }
                  }
                  cc.push("</div>");
                  cc.push("</td>");
              }
          }
          return cc.join("");
      };
      /**自定义函数，用于解决domain的嵌套问题   注意：此处的field肯定是字符串，但是row里面的key，可能为对象嵌套(后台加载数据)，也可能为字符串(前台页面传值)**/
      function getRowFieldData(row,field) {
          var flag = jQuery.isEmptyObject(row);
          if(flag){//如果是空行
              return row[field];
          }else{//不是空行
              if(isFieldMatchRowKey(row,field)){//如果row中包含该key
                  return row[field];
              }else{//对象嵌套方式
                  return eval("row['"+field.replace(/\./g,"']['")+"']");
              }
          }
      };
      /**判断列是否包含在row的key中，如果包含，说明为传值调用的刷新；如果找不到该列，说明为数据库对象嵌套的key**/
      /**数据只有两种情况，第一种:key为"a.b.c"而row的key也为"a.b.c";这种情况主要用于页面传值row(非嵌套或者用了format方法)***/
      /**第二种:key为"a.b.c"而row的key为"a['b']['c']";这种情况即为后台,或者传值调用的row(Json嵌套)的数据的组织方式***/
      function isFieldMatchRowKey(row,field) {
          var isInculde = false;
          for(var key in row){
              if(key==field){
                  isInculde = true;
                  break;
              }
          }
          return isInculde;
      };

      $.extend($.fn.datagrid.defaults.view, {  renderRow: _renderRow
      });

  })(jQuery);